Link to home
Start Free TrialLog in
Avatar of ExpExchHelp
ExpExchHelpFlag for United States of America

asked on

C++ -- Reading input file

I'm using a simple function to read an external text file (see attached "input.txt").

This function works fine and outputs the 10 integer values to the console.

I now need to process a modified version of the text file (see attached "input-Modified.txt"... obviously, its filename will have to be changed to "input.txt" later on).

The difference for these two files is obvious.    In file #1, I'm only reading 10 integers (1 per line).   The second textfile contains 3 integers per line.      

1. The first value (column) = "profit"
2. The second value (column) = "volume"
3. The third value (column) = "weight"

So, upon reading the modified input file, I'd like the 10 values of column 1 added into an array called "profit", the 10 values from column 2 should be added into array "volume", and so forth.

Although the current code does NOT "blow" up, it doesn't read the integers due to the "semicolon" separator.

How do I modify the existing code to accommodate assigning the 30 integers into the three mentioned arrays?

Thanks,
EEH
// Required C++ libraries and header files
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <math.h>											
#include <limits.h>
using namespace std;


// Declaration section
int i, j;
int linecount = 10;				  
int jobsTotal[1000];	


// Main() is the programs' "entry point"
int main()
{
	// Build object for using the input file
	ifstream myFile;										
	myFile.open("input.txt");
	

	// If file does not exist, feedback is output to console window
	if(!myFile.is_open()){									
		cout << "File 'input.txt' not found!" << endl << endl;
		system("PAUSE");
		exit(EXIT_FAILURE);
	}


	// File data (unsorted) is output to the console window (including the array reference)
	cout << "Step 1: The raw data (unsorted) are as follows:" << endl;
	cout << "===============================================" << endl;

	for (i=0; i<linecount; i++){									
		myFile >> jobsTotal[i];
		cout << "&[" << i << "] = " << jobsTotal[i] << endl;						
	}
	cout << endl << endl << endl;
	

	// Pause the window console screen
	system("PAUSE");
	return 0;
}

Open in new window

input.txt
input-Modified.txt
ASKER CERTIFIED SOLUTION
Avatar of DonConsolio
DonConsolio
Flag of Austria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of phoffric
phoffric

I don't see an attempt at your parsing the lines for this program, so I'll just start you off with some tips. Since this is the C++ zone, I'll keep it to C++ methods. You may be interested in a similar question:
    https://www.experts-exchange.com/questions/26324364/C-Parsing-a-string-from-an-input-file.html

You can use getline to read one line, for example:
getline ( myFile, line );

Open in new window

   http://www.cplusplus.com/reference/string/getline/

You can use find_first_of to locate the semi-colon:
found = line.find_first_of(";");

Open in new window

   http://www.cplusplus.com/reference/string/string/find_first_of/

You can use substr to extract a sub-string field:
field1 = line.substr( 0, found);

Open in new window

    http://www.cplusplus.com/reference/string/string/substr/

You can use atoi to convert a string of digits to the integer value.
    http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
(and for the last field, there is nothing to find or use substr on - you know the position in the string).
atoi requires a c-style string, so you need to convert the substring to a c-style string. You can use c_str to do this.
     http://www.cplusplus.com/reference/string/string/c_str/

It's just a matter of of getting the offsets right. (I suggest using the debugger to help figure out the offsets in the line.)

Avatar of ExpExchHelp

ASKER

DonConsolio:

Thanks... I only (2) places where I see reference to a semicolon is via "myFile >> dummy;"      But that's for the output to the console, right?    Was that all that's needed?

Final question... given that the fourth record has only two digits (vs. all others having three digits), what is the proper code to include printing at the next "tab stop" instead of just "space , space"... which result in not fully alignment values in the columns?

BREAK

phoffric:

Thanks for the tips... I appreciate it and will do some reading on these.


You can
- read the lines as text and parse the numbers/delimiters yourself
(as suggested by phoffric), which is best practice if you are programming
for a production environment.

- assume the file always is correctly formatted and no errors occur
and let the library do the parsing

 
                // read first integer from file (read to next non-numeric character - ";" in our case)
                myFile >> jobsTotal1[i]; 
                // read next character ( the ";" hopefully )
                myFile >> dummy;
                // read second integer from file (stops at ";")
                myFile >> jobsTotal2[i];
                // skip second ";"
                myFile >> dummy;
                // read last integer from file (read to newline)
                myFile >> jobsTotal3[i];

Open in new window

DonConsolio:

Clarification... as far as semi-colons is concerned, the file will always be in this format.    There will be instances where I have multiple 2-digit and 3-digit integers in a line.    Did you consider this << correctly formatted <<?

If so, am I reading it correctly that your suggested code won't allow formatting incl. tab stops?
ExpExchHelp:

Could you provide another input text file that represents all the formatting that you need to deal with. Then, the advice you get will be exact.
phoffric:

Sure... please see attachment.

I will have integers ranging between two and three digits.    As shown in the file, I potentially have records such as:
1. a record containing integers where all 3 values have three digits
2. a record containing integers where 1 value has two digits
3. a record containing integers where 2 values have two digits
4. a record containing integers where 3 values have two digits

However, as shown in the input file, the "two-digit" records can be in either of the three columns (1st position vs. 2nd position, vs. 3rd position).

So, again, any combination of the four combos above can occur.    In the end, if a tab stop is included that adds a generic width (always at least 3 digits) would suffice then.    Preferably, the two-digit numbers would be right aligned with the "column".

Makes sense?

input.txt
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
DonConsolio

Thanks for your help.

phoffric
Also, thanks for chiming in... and, yes, you were right, the follow-on question was really outside the original question.   If I still have uncertainty on this, I'll open up another question and link it.

Again, thanks to both of you!!
phoffric:

The width setting worked great!!!