Solved

C++ -- Reading input file

Posted on 2011-02-16
10
397 Views
Last Modified: 2012-05-11
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
0
Comment
Question by:ExpExchHelp
  • 5
  • 3
  • 2
10 Comments
 
LVL 15

Accepted Solution

by:
DonConsolio earned 450 total points
ID: 34913471
// 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 jobsTotal1[1000];
int jobsTotal2[1000];
int jobsTotal3[1000];
char dummy;

// Main() is the programs' "entry point"
int main()
{
        // Build object for using the input file
        ifstream myFile;                                                                             
        myFile.open("input-Modified.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 >> jobsTotal1[i];
                myFile >> dummy;
                myFile >> jobsTotal2[i];
                myFile >> dummy;
                myFile >> jobsTotal3[i];
                cout << "&[" << i << "] = "
                        << jobsTotal1[i]  << " "
                        << jobsTotal2[i]  << " "
                        << jobsTotal3[i]
                        << endl;
        }
        cout << endl << endl << endl;


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

Open in new window

0
 
LVL 32

Expert Comment

by:phoffric
ID: 34913490
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:
    http://www.experts-exchange.com/Programming/Languages/CPP/Q_26324364.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.)

0
 

Author Comment

by:ExpExchHelp
ID: 34915028
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.


0
 
LVL 15

Expert Comment

by:DonConsolio
ID: 34915948
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

0
 

Author Comment

by:ExpExchHelp
ID: 34922244
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?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 32

Expert Comment

by:phoffric
ID: 34922475
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.
0
 

Author Comment

by:ExpExchHelp
ID: 34922851
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
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 50 total points
ID: 34923190
While output of your data is a separate question from your OP, I'll give you an answer anyway.
Shown below is setw example taken from http://www.cplusplus.com/reference/iostream/manipulators/setw/

You can also give this a try:
    cout << setiosflags(std::ios::right); // or left
// setw example
#include <iostream>
#include <iomanip>
using namespace std;

int main () {
  cout << setw (10);
  cout << 77 << endl;
  return 0;
}

Open in new window

0
 

Author Closing Comment

by:ExpExchHelp
ID: 34924839
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!!
0
 

Author Comment

by:ExpExchHelp
ID: 34924887
phoffric:

The width setting worked great!!!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now