ok...i am trying to figure out how to read input ....

i am reading input from the command line

sh% ./a.out < input_file

within the input_file, it looks like this:

0 4 6 7 3
1 3 6 7 4 3 6
2 3 6 7 3 2 4 6 7 7
3 5
4 3 2 9 1

and im looking to read in the whole thing .... in each line, the first number is the item #, and the rest of the numbers is some attributes for that item number ... and each line is a different item # ...

i know how to get it to read in the whole file:

while (!cin.eof())
{
//reads in everything until the end of the file
}

but how do i get it to read in until the end of the line (every line can have a different number of attributes)?

i was going to have another while loop within it?

here is some code:

#include<iostream>

int main()
{

  int input;

  while (!cin.eof())
  {
  //reads in everything until the end of the file

    while (?????)
    {
       //reads in each line
    }

  }

do i read until i find \n ?

while (input != '\n')

??

any help would be great..thanks

Greetings jaeSun,

There are a few ways you could accomplish this task. I do see you are using iostream, so I'll stick with its functionality.

  • Use the while loop
  • Use the iostream read() function

Both are uesful, and can be relied on for different projects. Let me explain both.

Using the while loop
When using the while loop with a stream, you may be familiar with eof(). All eof stands for is End Of File. Since we are dealing with iostream, we are going to use its function get().

int get();
get() extracts a character from the stream and returns its value.

Firstly, I will split the code in sections for further detail.

#include <iostream>
#include <fstream>
using namespace std;

This simply defines we are to use these header files in our program. fstream provides a stream interface to read and write data from/to files.

int main () {
	char c, str[256];
	ifstream is;

	// Open file
	is.open("Your file");

	// Loop while extraction from file is possible
	while (is.good()) {
		// Get character from file
		c = is.get();
		cout << c;
	}

	// Close file
	is.close();

	return 0;
}

» The function open() opens a file. The stream's file buffer is associated with the specified file to perform the i/o operations.

» Instead of calling eof(), we will call good() as it checks if stream is good for i/o operations. The function returns true if none of the stream's error flags are set.

» Next we call get(), as it gets the next character in the stream indefinetly in our while loop until it breaks.

» After that, we close the file.


Use the iostream read() function
This way of reading a file is a bit more complex, but is a more efficent way of reading the stream into memory.

#include <iostream>
#include <fstream>
using namespace std;

int main () {
	int length;
	char *buffer;
	ifstream is;

	is.open("Your file", ios::binary);

	// Get length of file
	is.seekg(0, ios::end);
	length = is.tellg();
	is.seekg(0, ios::beg);

	// Allocate memory
	buffer = new char[length];

	// Read data as a block
	is.read(buffer, length);

	// Close file
	is.close();

	// Print data
	cout << buffer << endl;

	// Free memory
	delete []buffer;

	return 0;
}

There are some new functions used like seekg() and tellg().

» seekg() sets the position of the get pointer. The get pointer determines the next location to be read in the buffer associated to the input stream.

istream& seekg( streamoff off, ios_base::seekdir dir);

  • ios_base::beg - beginning of sequence.
  • ios_base::cur - current position within sequence.
  • ios_base::end - end of sequence.

» tellg() returns the position of the get pointer. The get pointer determines the next location to be read in the buffer associated to the input stream.

So its simple on how our process for the length of our stream worked. Go to the end of the file, get the length, take it back to the beginning and read it.

» The new and delete keywords are to help you allocate memory use at runtime. The keyword new will allocate a chunk of memory within your program and delete will deallocate it. You will probably also want to keep track of these chunks by using pointers.

» Once we are done, we read the stream into our newly allocated buffer with the specified amount of length for our string.

istream& read (char* s, streamsize n);
read() reads a block of data of the length specified by n. Data is read sequentially, so if the End-Of-File is reached before the whole block could be read the buffer will contain the elements read until End-Of-File.

Conclusion
I hope this information has been useful. If you have further questions, please feel free to ask.


- Stack Overflow

ok...so then i can do this: ?

#include<iostream>

int main()
{
  char input[200];

  cin.getline(input, 200);

  while (cin.good())
  {

    //modify the character line as needed 
    //(i will need to convert from char to int value)
    //which i can use another while loop to pull the first character,
    //get the digit, get the next character, get the digit, until 
    //i find a space ... then get the next number, until I find a NULL
    //which means its at the end of the line (the getline() replaces
    //the \n with a  NULL ??

    cin.getline(input, 200);
  }

  return 0;
}

??

also, we have to use unix redirection, instead of opening and closing a file..... this is my homework assignment, and he didnt specify what file he be using for inputting everything ....

Checking the line input using getline() or eof() is fine. There are two possible ways of doing this:

#include <iostream>
using namespace std;

int main() {
	char input[200];

	cin.getline(input, 200, '\n');
	while (!cin.eof()) {
		// Do stuff here...

		cin.getline(input, 200, '\n');
	}

	return 0;
}

Ah, a third parameter for getline().

» istream& getline (char* s, streamsize n, char delim);
If the delimiter is found it is extracted but not not stored. Use get() if you don't want this character to be extracted. This parameter is optional, if not specified the function considers '\n' the delimiter.

Instead of using the while loop on eof(), we could just use getline() instead:

#include <iostream>
using namespace std;

int main() {
	char input[200];

	while (cin.getline(input, 200, '\n')) {
		// Do stuff here...
	}

	return 0;
}

Either way it accomplishes the same task.


- Stack Overflow

If you can use stringstreams, then you can just use getline for each line and then use a stringstream of the line to pick off the ints.

#include <iostream>
#include <sstream>
#include <string>

int main()
{
   std::string line;
   while ( std::getline(std::cin,line) )
   {
	  std::istringstream iss(line);
	  int value;
	  while ( iss >> value )
	  {
		 std::cout << value << ',';
	  }
	  std::cout << '\n';
   }
   return 0;
}

/* my output
C:\Test>testpp < file.txt
0,4,6,7,3,
1,3,6,7,4,3,6,
2,3,6,7,3,2,4,6,7,7,
3,5,
4,3,2,9,1,
*/

ok, your going to have to bear with me (sorry, i feel like im running with my head cut off...hw assignment is due tomorrow, and yes, i should have started earlier) ......

i was getting each line, and then using the strtok function to break it up into each of its own ... and then compare the char and convert to int ..... didnt work ....

this is the code i had:

char input[200];
  string tokout;
  int num;


  cin.getline(input, 200);
  cout <<input<<endl;  //prints out the whole line of numbers
  tokout = strtok(input," \n\t");  //gets the first number
  cout <<tokout<<endl;  //prints the first number
  while (tokout != NULL)     //while loop to get the rest of the numbers
    {
      tokout = strtok(NULL," \n\t");
      cout <<tokout<<endl;
    }
  cout<<endl;

it works, prints out all the numbers into the line ... BUT, when it gets to the end, it gives a segmentation fault ...

i thought when it couldnt strtok anymore (basically, reaches the end of the line), it returns a NULL. but i guess i cant compare tokout to NULL ?? (compiler says cant compare tokout to int, or im guessing its saying that i cant compare a string to a NULL ..

i did a similiar thing in C and it worked, but guess not in C++ ??

questions on stack overflow's code:

1. in your while loops, what if there is only 1 line, thus, no \n at the end? will it still process that line? im guessing it will, since it says to go 200 characters, so it will do whichever comes first, or in the case of no line, go as far as it can?

questions for dave:

1. ok, ive never messed with the sstream's at all ... actually, never heard of it until now ....and im having a hard time understanding your code ... :confused:

ive tested it out... and it works ... i can add and subtract ...but im having a hard time distinguishing when it goes to the next line ....

grrrrr

#include <iostream>
 #include <cstring>
 using namespace std;
 
 int main()
 {
    [b]char [/b]input[200], [b]*tokout[/b];
    int num;
 
    while ( cin.getline(input, 200) )
    {
 	  cout << input << endl;  //prints out the whole line of numbers
 	  tokout = strtok(input," \n\t");  //gets the first number
 	  while ( tokout != NULL )	 //while loop to get the rest of the numbers
 	  {
 		 cout << tokout << endl;  //prints the first number
 		 tokout = strtok(NULL," \n\t");
 	  }
 	  cout<<endl;
    }
    return 0;
 }

is there a site which will explain the sstream functions?

i have searched around, and havent found much ...

cplusplus.com doesnt have it?

Yes,

You can learn more about stringstream, and other C++ streams such as fstream, iostream, and streambuf at: http://cplusplus.com/ref

Or just learn more about stringstream here.


Hope this helps,
- Stack Overflow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.