stuck on read file C++

Started by
8 comments, last by Zahlman 17 years, 5 months ago
this is what i came up with, needless to say there are BUGS.....Hellllp! char file_hazard = ' '; vector<char> hazard; if (string(argv[1]) == "-debug") { debug_populate(grid, num_rows, num_col); } else if ( argc >= 3 && string(argv[1]) == "-f" ) { ifstream infile(argv[2]); if(infile.fail()) open_file_error(argv[2]); else if(!infile.eof()) { for(int i = 0; i < hazard.size(); i++) { infile >> file_hazard; hazard.push_back(file_hazard); } } //else //file_map_generator(grid, num_rows, num_col); }
Advertisement
It would help to see that fragment in the larger context of an entire program in order to diagnose all the problems with it, especially since you have not adequately described the "BUGS" you observe. Also use [ source ] and
[ /source ] tags (without the extra spaces) to mark large sections of code, since it will preserve formatting. Your sample is rather unreadable as-is.

The immediate issue seems to be the for loop, which gates on i < hazard.size(). Except that you never resize, fill, append to or otherwise adjust the size of the hazard vector, and so size() will be returning 0 and the loop will simply never execute.
thanks jpetrie, for the formatting trick...
And yes that is what I came up with - '0' - ineffectively populating the vector with the file 'char' elements, which is what im trying to do by reading from a file with a format (dynamically) similar to this,
xwp
xxx
xxg
where each char is read in one by one, row by row(not coded yet)
char file_hazard = ' ';vector<char> hazard;if (string(argv[1]) == "-debug"){    debug_populate(grid, num_rows, num_col);}else if ( argc >= 3 && string(argv[1]) == "-f" ){    ifstream infile(argv[2]);    if(infile.fail()) open_file_error(argv[2]);else if(!infile.eof()){    for(int i = 0; i < hazard.size(); i++)    {         infile >> file_hazard;         hazard.push_back(file_hazard);    }}

the focus being on populating the vector here
Like I said: the loop won't execute, hazard.size() is 0. You can say you want to populate the vector all you like, but your code isn't going to ever do that because you've written it wrong. Instead of gating the loop on the size of the vector, you want to read a char at a time until you've read the whole file. You probably also want to throw out newlines. For example:
std::vector< char >  hazard;std::ifstream        file("file.txt");  while(!file.eof())  {  char input = 0;      // Read a character.    file >> input;    if(input != '\n')      hazard.push_back(input);  }
Step back and describe - in English, but IN DETAIL - exactly how you want to interpret the file data.

For now, omit any references to data types or containers.

How much do you want to read? (Valid answers would be things like "the whole file"; "the number of characters indicated by a number at the beginning of the file"; etc.)

What is the fundamental structure of the data? (Valid answers would be things like "None, just a whole dump of raw text"; "a sequence of logical 'lines' of text, each on its own physical line, i.e. separated by newlines"; "a sequence of chunks of data corresponding to X format, each of which describes an object of type Y", etc.)

How can you determine, *given only the file data*, when to stop reading data - for the whole process? For a given component of the overall structure? (A great many valid answers are possible here, but should correlate to whatever you said for the first two questions).

Is there any possibility for ambiguity? Are you sure? Can you prove it? (If you're not sure, see here for some tips on making file formats that will actually work.)

What kinds of errors are possible (i.e., in what ways could the file data be invalid)? What kind of error checking (if any) is desired/needed? If an error is found, how will you handle it? (Valid answers can include "skip the current line and continue processing as if that line were not in the file"; "terminate the file reading process, clean up and report an error"; "use a simple heuristic (be specific) to correct the data".)
Thanks again jpetrie.

I apologize about the cryptic codes, I am quite new at C++
This forum has been very helpful with my learning.
Now with some [ source ] and [ /source ] understanding i will be able to post more legible code examples.

peace
Quote:Original post by jpetrie
For example:
std::vector< char >  hazard;std::ifstream        file("file.txt");  while(!file.eof())  {  char input = 0;      // Read a character.    file >> input;    if(input != '\n')      hazard.push_back(input);  }


This will probably give you a garbage character at the end of the vector. Remember that .eof() only returns true after a failed read operation. If you're reading a character at a time, it's usually best to use .get(), store the result in an int, compare that to EOF, and if it's not EOF, cast that data to a char and store it. Then repeat.
Hmmm, ok i'll try again....
with a slight modification the code provided by jpetrie (which helped) is working correctly as follows,
        if (string(argv[1]) == "-debug")        {		debug_populate(grid, num_rows, num_col);	}	else if ( argc >= 3 && string(argv[1]) == "-f" )	{        ifstream infile(argv[2]);        if(infile.fail()) open_file_error(argv[2]);        while(!infile.eof())        {	     char file_hazard = 0;	     infile >> file_hazard;	     if(file_hazard != '\0')	          hazard.push_back(file_hazard);        }

what modification do i need to make to read a .txt file formatted like this;
xwp
xxx
xxg

to separate each line from the next and record its length one by one even if the
.txt file is larger:

xxxxx
wxxpx
gxxxx
xxxxw

accessing the vector is (amazingly) no prob so far, i am considering a pointer option, or possibly a vector of vectors to represent the .txt format which will always be a rectangle (or square). given the ammount of individual chars is recorded correctly from the above code using;
cout << hazard.size() << endl;


i hope i am explaining this right and any suggestions are welcome...
#! perl

open INPUT "input.txt" or die "Error opening file!";
@_ = <INPUT>;

print foreach @_;
Quote:Original post by Ultimape
#! perl

open INPUT "input.txt" or die "Error opening file!";
@_ = <INPUT>;

print foreach @_;


Don't troll. (There is clearly a larger context here; the data is deliberately being read into a structured container for use by a larger program, the behaviour of which is not known. There is no reason to assume another language is the best tool for the job.)

OP: The code so far doesn't care how much text is on each line, but it removes the line breaks and squishes everything into a single vector.

If you want to keep track of individual "lines" in some way, then you still need to step back and think: Should all lines be the same length? If so, what should the program do if it gets a file where that isn't true?

If not, a simple solution is to treat each line as a separate object, and make a vector of those objects. The "line objects" could either be std::string (if the line is supposed to represent an actual line of text) or std::vector<char> (seems more appropriate for what you've shown; this is some kind of map data, right?).

To read a line of text at a time, we can use the free function std::getline(). It reads into a std::string object, but we can easily copy from there into a vector of char (or more accurately, construct a vector of char with the string's contents), and that saves us from the manual looping to read each character.

typedef vector<char> line;vector<line> map;string buffer;while (getline(file, buffer)) {  map.push_back(line(buffer.begin(), buffer.end()));}


That should read the entire file, without any weird EOF problems, but it doesn't try to enforce any rectangularity etc.

Also, read this.

This topic is closed to new replies.

Advertisement