Thread: File I/O questions

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    10

    File I/O questions

    Using MS Visual C++ 6.0.
    Command line project.

    I'm trying to write a project (as part of an assignmet) that reads all text from a .txt document and breaks each word down into seperate string segments.

    I'm stuck at the part where I'm reading the file. I'm using ifstream for the file input. I am reading the file just fine using
    Code:
    filename_variable.get();
    I'm using a while loop, and pushing the characters I get from the file to a vector.

    The Problem: The problem I'm having is that I can't get the while loop to recognize eof on the file.

    Can anyone give me some ideas here?

  2. #2
    Registered User
    Join Date
    May 2004
    Posts
    164
    What delimeters are you passing to the get()? If I am not mistaken, which I may be, since I typically do getline vs get, I think you can pass delimeters characters to the get() so it knows how to separate input values.

    Also, I got this from a C++ instructor at my university years ago, thought it was silly until I started using getline and get functions:

    This is a call to eat up any white spaces, non-characters, to run to the end of file and set the eof bit.
    Code:
    fin>>ws;
    and

    this call which sets the end of file bit at the last record input
    Code:
    ifstream fin;
    fin.open("C:\\somefile.txt", ios::eofbit)
    better programers on this board may call me a quack because they understand it better, but I often use these when doing mass file inputs from text files where I have no clue what may be input and where eof may be. take this with a grain of salt as I am not the a C++ guru by any sort, but these helped me out on certain programs, so they may help you. I can post sample code if you need it where I used it and it made a difference. GOOD LUCK.

  3. #3
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Code:
    #include <sstream>
    #include <vector>
    #include <string>
    
    string line, parse;
    vector<string> words;
    ifstream infile("nameoffile.txt", ios::in);
    while(infile)
    {
        getline(in, line);
        istringstream words(line);
        while(words >> parse)
                  words.push_back(parse);
    }

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    words vector and words stringstream should have different names
    also getline(infile
    and #include <fstream> is required
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    10
    My mistake, I forgot to post my code:
    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <sstream>
    #include <cmath> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    const char dictionary[14] = { 'a', 's', 'c', 'i', 'i', '_', 'd', 'i', 'c', 't', '.', 't', 'x', 't' };
    ifstream dictInput;
    vector <char> dictVect(0);
    char n;
    
    int main()
    {
    dictInput.open(dictionary);
    
    if (dictInput.is_open())
    	{
    		
    		while ( !ios::eof() )
    		{
    			if (!ios::eof())
    			{
    				n = dictInput.get();
    				cout << n;
    				dictVect.push_back(n);
    			}
    			else
    				// Do nothing
    		}
    		cout << endl;
    	}
    
    return (0);
    }
    As it is right now, this can't compile. I'm getting error:
    project.cpp(207) : error C2352: 'std::ios_base::eof' : illegal call of non-static member function

    The filename is ascii_dict.txt, and it reads it well. My main problem is that I don't know how to get it to find end of file on ascii_dict.txt.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    1. <cstdio> and <cstdlib> should be used in C++
    2. dictInput.eof() not ios::eof()
    3.
    Code:
    			else
    				// Do nothing
    should be
    Code:
    else
    {
    	// Do nothing
    }
    4. don't use eof to control a loop - read FAQ
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    can't get the while loop to recognize eof on the file.
    Your read statement should be the while loop conditional:
    Code:
    char ch;
    while( myInputFile.get(ch) )
    {
    	cout<<ch<<" ";
    }
    cout<<endl;
    cout<<"end of file was reached(or a read error occurred)"<<endl;
    However, accessing a file is slow, so you should read big chunks of it at once into a variable--not one character at a time.
    Last edited by 7stud; 01-16-2007 at 12:07 AM.

  8. #8
    Registered User
    Join Date
    Aug 2006
    Posts
    10

    Thumbs up

    dictInput.eof() not ios::eof()
    WOO HOO!!!!!!!!!!!!! That did it! Son of a @#$%& I hate it when I do that with syntax. LOL. Thanks.

    I see what you mean by not using EOF for loop control. Would it be wiser for me to use gcount() and a for loop?

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by jedispy
    I see what you mean by not using EOF for loop control. Would it be wiser for me to use gcount() and a for loop?
    Since you are looping while being successful at input, would it not simply be easier to loop while you are successfully receiving input?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    WOO HOO!!!!!!!!!!!!! That did it!
    No reason for celebration. Your approach is wrong. Suppose you use eof as the loop control. What happens if there's an error while reading from the file which prevents you from reading anymore data(which is what will happen when an error occurs)? When the error occured were you at eof? No. And, since you aren't able to read anymore data, will you ever hit eof? No. So what happens to your while loop? It will become an infinite loop. Bad program.

    Now what happens if you use your read statement as the while loop conditional. The read statement returns the filestream object after it executes, so your while statement becomes:
    Code:
    while(myInputFile)
    {
    
    }
    If eof is hit, then a flag will get set in myInputFile, and the flag will cause myInputFile to evaluate to false in the conditional, causing the while loop to terminate. If any error occurs while reading from the file, then error flags will get set in myInputFile, causing myInputFile to evaluate to false, and then the while loop will terminate. Good program.
    Last edited by 7stud; 01-16-2007 at 09:03 AM.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> If eof is hit, then a flag will get set in myInputFile, and the flag will cause myInputFile to evaluate to false in the conditional, causing the while loop to terminate.

    Note that this is not technically true. If the end of file is reached during a successful read, then the eofbit will be set but the failbit will not. This will cause the loop to run again (which is what you want since the read succeeded). while(myInputFile) will only be false when the failbit is set, not eofbit. You are ignoring eof completely with this solution, and allowing a failed read (because the file stream is empty) to break the loop.

    (This comment stays in this thread).

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    If eof is hit, then a flag will get set in myInputFile, and the flag will cause myInputFile to evaluate to false in the conditional, causing the while loop to terminate.

    Note that this is not technically true.
    Yes, you're right.

    You are ignoring eof completely with this solution:
    I believe it does what the op wants to do, that is: read in all the characters in the file and then stop.

    allowing a failed read (because the file stream is empty) to break the loop.
    How would a file stream be empty unless there was a read error or eof had been encountered? In either case, the loop should end. What situation do you have in mind?
    Last edited by 7stud; 01-16-2007 at 07:52 PM.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    First, I want to say that I misread your original code. I was thinking of while (inputFile >> variable) or while (getline(inputFile, variable)). Those would be better than while (inputFile), since you would need an extra if or you would need to read at the end of the loop to ensure that the state was checked before the variable was used.

    >> I believe it does what the op wants to do
    Assuming the read is included in the while control, it does, I was just pointing out a minor technicality on why. Now that I look again I see that as it is you need to add the code to read from the filestream, and whether it reads from the file and stops correctly depends on where you put that read.

    >> How would a file stream be empty unless there was a read error or eof had been encountered?
    If the read reads in all the data in the file. For example, if the file is terminated with a newline and you are reading with getline, then the last call to getline will succeed, but neither failbit nor eofbit will be set despite the fact that the file stream is empty. Only the next attempt to read will fail and set both the failbit and eofbit. This is correct, as you want to execute the loop block if getline read in the last line even if it left an empty stream, and you want the next read to fail and break the loop.

  14. #14
    Registered User
    Join Date
    Aug 2006
    Posts
    10
    I've got this part working now. However now I'm stuck at another point. It's frustrating too. All I want to do is compare elements in a char vector for specific char values.

    Firstly let's assume that the "dictionary" file reads the phrase "how now brown cow". (each word is seperated by tabs, not spaces). I want to scan through the char vector for the tab character.

    Here's basically what I'm doing:
    Code:
    	for (int j = 0; i < dictVect.size(); i++)
    	{
    
    		if (dictVect[j] == "	" )     //  This is where my problem is
    		{
    			// Do something
    		}
    	
    
    	}
    As I state in the code above, my problem is with the line that reads if (dictVect[j] == " " )

    When I do this, the compiler seems to be trying to convert char * to int. I don't get it because I'm not using any integers. All I want to do is compare the char elements of the vector with the tab character.

    Hrm....I guess that " " is a string, and not a character.

    Is that my problem right there?

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Yes.

    To indicate the tab character, use '\t' with the single quotes. Single quotes are for characters, double for strings. Special characters like tab and newline require escape sequences, which are the escape character followed by another character. In C++ backslash is the escape character.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File I/O Assertion Failure in VS2008
    By clegs in forum C Programming
    Replies: 5
    Last Post: 12-25-2008, 04:47 AM
  2. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM