How to I/O a file line by line??

This is a discussion on How to I/O a file line by line?? within the C++ Programming forums, part of the General Programming Boards category; Hi, I am working through a few small C++ projects, one of which is read the contents of a file ...

  1. #1
    Unregistered
    Guest

    Question How to I/O a file line by line??

    Hi,

    I am working through a few small C++ projects, one of which is read the contents of a file (a few lines, say 1,2,3) and output them in reverse order to another file.

    I am new to C++, and have looked through quite a few resources about getline, read, peek, etc etc but can't nail the problem on the head. I can retrieve the whole contents, the first line or the last line but can't get data line by line !

    If someone could point me in the right direction as to the right commands and so forth, and how to grab and store the data in reverse order it would be greatly appreciated.

    Regards,
    Liam.

    my code so far:

    #include <iostream.h>
    #include <fstream.h>

    int main()
    {
    char buffer[256];
    ifstream source ("liam.txt");
    while (! source.eof() )
    {
    source.read (buffer,100);
    }

    ofstream target ("output.txt");
    if (target.is_open())
    {
    target << buffer;
    target.close();
    }
    return 0;
    }

  2. #2
    Unregistered
    Guest
    change this:

    source.read (buffer,100);

    to this:

    source.getline(buffer, 100);

    declare an array of strings (or a list or vector or some other container to store your strings as you read them, a stack would work cute since it is last on first off by definition) and an int to keep track of the last index used in the array of strings. As you read in each line from the file place it as an intact string in the first available element of the array (use strcpy() if placing c_style string in an array of c_style strings. Once you have read the entire file write to the new file starting with the last string element in the array and continue reading out each string element by decreasing the element index to be read each time through a loop.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    also remember that eof() checks to see if you have read PAST the end of file marker, so...
    Code:
    ifstream in("file.txt");
    char info[80];
    for(int x = 0; !in.eof() ; x++)
      in.getline(info, 80);
    x will be 1 more than the number of lines in file.txt if no line is longer than 79 characters

  4. #4
    Unregistered
    Guest
    so eof() looks if you have read PAST the EOF marker, huh. Maybe that explains some funky behavior I have had in the past. If I understand Syneris correctly, if I place a newline after the last file input and use getline() to read file back at a later date, then getline() will stop at the last newline (assuming default behavior), then procedd to read EOF and the next 79 char, whatever they are, before it stops, place that junk in the last buffer, do whatever with the last set of chars in buffer, and then quit the loop at the next cycle. Thus resulting in one more input that expected from the file. Is that correct? If so, then that's probably the reason for priming the loop when using a while loop; like this:

    ifstream fin ("myfile.txt");
    int value;

    //prime read
    fin >> value;

    while(!fin.eof())
    {
    //manipulate input somehow
    cout << value;

    //THEN get next read in
    fin >> value;
    }

    RATHER THAN

    ifstream fin("myfile.txt")
    int value;

    while(!fin.eof())
    {
    //get value first
    fin >> value;

    //then manipulate
    cout << value; //this may well be junk/unexpected result
    }

    THANKS Syneris!

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >Thus resulting in one more input that expected from the file. Is that correct?
    Exactly correct, but it's better to read your data from the file in the loop condition and then check to see if it's EOF. If it is then you can break from the loop without processing the invalid data. If you check for EOF in the loop then the check will be made before the flag is set, resulting in one more read than you want.
    Code:
    while ( !feof ( fin ) ) /* Bad */
    while ( fgets ( buf, sizeof buf, fin ) != NULL ) ) /* Good */
    If your input read fails then there was either an error or eof which you can determine with ferror() or feof() in an if statement. Using an EOF check in a loop condition is the incorrect way to use feof().

    -Prelude
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    since EOF is a special mark at the end of every file, i'm not exactly sure what getline does with it.
    Code:
    char string1[80];
    cout << "Starting Input..." << endl;
    in.getline(string1, 80);
    cout << "Getline*" << string1 << "*End Getline" << endl;
    displays:
    Starting Input...
    Getline**End Getline
    i assume that getline recognized the eof marker and null terminates string1 right away

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    getline is delimited by a newline as the default argument, but you can change that by setting the optional third argument like so:
    getline ( array, SIZE, EOF );
    Play around with this a bit, to end the loop simply type ctrl+c or ctrl+z to flag EOF.
    Code:
    #include <iostream>
    using namespace std;
    
    int main ( void ) 
    {  
      char array[80];
      while ( cin.getline ( array, 80 ) )
        cout<<"good"<<endl;
      cout<<"EOF reached"<<endl;
      return EXIT_SUCCESS;
    }
    And I just noticed that I mistook this thread for a C thread in my last post :P

    -Prelude
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    hmm is it possible that the eof marker is treated like a null character? hmmm...
    tested this:
    Code:
    char string1[80];
    cout << "Starting Input..." << endl;
    in.getline(string1, 80);
    if (string1[0] == '\0')
      cout << "Getline*" << string1 << "*END GETLINE" << endl;
    displays the same results as before, which leads me to believe that it is translated to \0 upon input
    Last edited by Syneris; 03-13-2002 at 10:54 AM.

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >which leads me to believe that it is translated to \0 upon input
    That's not entirely correct, getline will read until it reaches one of three conditions: There is an error while reading, EOF is reached, or a delimiting value is reached. When any of those conditions are met, getline will have written everything *up to* the point where reading stopped and then append a \0 on the end of the array.

    If getline reads EOF, has an error, or reads any of the delimiters as the first character then it will still append a \0 to the array, which describes the behavior that you were getting.

    -Prelude
    My best code is written with the delete key.

  10. #10
    Unregistered
    Guest
    so EOF delimits getline() even if terminal char hasn't been found or input size limit hasn't been reached? cool.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help again with scrolling without wrapping
    By Dukefrukem in forum C Programming
    Replies: 8
    Last Post: 09-21-2007, 01:48 PM
  2. File I/O Question
    By Achy in forum C Programming
    Replies: 2
    Last Post: 11-18-2005, 12:09 AM
  3. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 05:10 PM
  4. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM
  5. Greenhand want help!
    By leereg in forum C Programming
    Replies: 6
    Last Post: 01-29-2002, 06:04 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21