cin.getline()

Started by
7 comments, last by randomDecay 22 years, 5 months ago
Hey all. I am reading line-by-line from a file using C++ in a console program. Here is what I have on one line that I want to stick in variables: 1, 6 49 1 0 1,6 are the x,y coords 49 is the ASCII value of a character symbol 1 is its visible state 0 is the color here is what I have so far to do this:
  
	inputFile.getline( buffer, BUF_SIZE );
		
			m_nCells = atoi( buffer );
			cout << "Number cells = " << m_nCells << endl;
		
			// Get cell coords, ASCII character, visibility state

			// and color for each cell

			for ( int i = 0; i < m_nCells; i++ )
			{				
				inputFile.getline( buffer, BUF_SIZE );

				coordX = atoi( buffer );

				int index = 0;
				while ( buffer[ index ] != ''\0'' && buffer[ index ] != '','' )
				{
					index++;
				}
				if ( buffer[ index ] = '','' )
				{
					coordY = atoi( &buffer[ ++index ] );
				}
				else
				{
					coordY = 0;
				}

				cout << "x = " << coordX << " " << " y = " << coordY << endl;

				Cell *ps = &cell[ coordX ][ coordY ];
				ps->symbol = atoi( &buffer[ index + 2 ] );
				cout << "Symbol = " << ps->symbol << endl;
				
				ps->visible = true;
				cout << "Visible = " << ps->visible << endl;

				ps->color = atoi( &buffer[ index + 8 ] );
				cout << "Color = " << ps->color << endl;
  
basically it works, but I haven''t figured out a better way or cleaner way to do this...anyone want to help? And I couldn''t figure out how to get a bool value out of the visible state, seeing as how I set up my struct so that I have a variable called bool visible. So for the time being I just made it true.
Advertisement
You can try using the standard C function strtok to parse the strings. strtok will divide the string into smaller strings by finding delimiters and replacing them with /0.

For example, for the string "1, 6 49 1 0", strtok could be used like this:

inputFile.getline( buffer, BUF_SIZE );char *x, *y, *symbol, *visible, *color;char *delim = ", ";x = strtok(buffer,delim);y = strtok(NULL,delim);symbol = strtok(NULL,delim);visible = strtok(NULL,delim);color = strtok(NULL,delim); 


The first call to strtok finds the first token separated by delimiters, inserts a /0 after it, and returns a pointer to that delimiter. In each subsequent call, NULL is passed to strtok instead of a string. strtok stores internally where it was in the string, and calling NULL will tell it to continue parsing where it left off. It will insert a /0 after the next token and return a pointer to it. If it reaches the end of the string, it simply returns NULL.

In this way the string can be parsed into smaller strings very easily and cleanly. This code can be followed by a code segment that will convert each string into an integer, using atoi. Each of the strings can be checked to see if it is null, to try to detect bad input.

Note that the delimiters I used here were a comma and a space. Any characters can be put into the delimiter string. These delimiters will be treated as white space by strtok and will separate the tokens that it returns. Each call to strtok may use its own delimiter string.
That sounds good, thanks. But is there a way to do it using C++?
Why not simply
  int tmp;inputFile >> coordX >> coordY;Cell *ps = &cell[coordX][coordY];inputFile >> ps->symbol;inputFile >> tmp;ps->visible = (tmp == 1);  


-Neophyte
Does that take into account the stupid comma?
"Pure" C++:
#include <cstdlib>  // definition for atoi#include <fstream>#include <iostream>#include <string>  //int main(int argc, char *argv[]){  // assume ifstream opened and validated  // parse a single line:  string coords;  int x, y, iAscSym, iVisible, iColor;  //  infile >> coords >> iAscSym >> iVisible >> iColor;  int pos = coords.find_first_of(",", 0);  if(pos == string::npos)  {    cout << "Mis-formed coordinate pair" << endl;    return -1;  }  x = atoi((coords.substr(0,pos)).c_str());  y = atoi((coords.substr(pos, coords.size() - pos)).c_str());  ...  // use data  return 0;} 
do you have a Point class? If so just write an input operator for it. Then you can pull a point out of a stream directly. Of course you''ll implement the Point input operator using the more basic input operators but it works quite nicely.

Of course if you want a simple fix just leave out the comma, or put spaces on both sides of the comma and skip over it by reading it into a string.
Ah, I didn''t actually notice the comma.
To cope with that you can do:
  int tmpi;char tempc;inputFile >> coordX >> tempc >> coordY;Cell *ps = &cell[coordX][coordY];inputFile >> ps->symbol;inputFile >> tmpi;ps->visible = (tmpi == 1);  


-Neophyte


- Death awaits you all with nasty, big, pointy teeth. -
Thanks to all for the help :D

This topic is closed to new replies.

Advertisement