CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    May 2001
    Posts
    153

    Reading data from file

    Hi Gurus,

    I have this problem. I am reading data from a file, simple text lines. The program works fine on windows, however, on unix, it reads the last line twice ... I am perplexed.

    Here's the code:

    Code:
    while(!(dataFile.eof() || dataFile.bad() || dataFile.fail()))
    {
        char buffer[HPGL_TOOL_MAX_LINE_LENGTH+1];
    
        dataFile.getline(buffer, HPGL_TOOL_MAX_LINE_LENGTH); 
    
    cout << "buffer = " << buffer << endl;
    			
        // Add to the part list
    			
        partNameList.push_back(buffer);
    }
    The output (on unix) is:

    buffer = /if/21174/2117400-1.prt
    buffer = /if/21378/2137813-0.prt
    buffer = /if/21378/2137813-0.prt

    The data file is:

    /if/21174/2117400-1.prt
    /if/21378/2137813-0.prt

    Please help!
    Kamran

  2. #2
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    What OS and compiler are you using? I've run the thing on Windows NT 4.0 SP6a, HP-UX 10.20 with gcc 3.1, and some digital unix box with gcc 3.0 and the output is the same on each. I'm guessing it's your compiler's implementation of getline().

    UX1:/data/pwendt_ux1/test/exe>./str_block
    buffer = /if/21174/2117400-1.prt
    buffer = /if/21378/2137813-0.prt

    UX1:/data/pwendt_ux1/test/exe>gcc --version
    gcc (GCC) 3.1
    Copyright (C) 2002 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    --Paul

  3. #3
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968
    You should use the global getline function instead.
    The global getline function works with an std::string.

    Example:

    while(!(dataFile.eof() || dataFile.bad() || dataFile.fail()))
    {
    std::string MyStrBuffer;
    std::getline(dataFile, MyStrBuffer);
    cout << "MyStrBuffer= " << MyStrBuffer<< endl;

    // Add to the part list

    partNameList.push_back(MyStrBuffer);
    }

  4. #4
    Join Date
    Jan 2001
    Posts
    588
    I think the problem in your code is due to how your loop works. The .eof() condition is not triggered until after you try to read past the end of the file. For instance, when you read the last line of the file, .eof() is not triggered, so the loop continues for one more iteration. You try to get another line from the stream, but it finds that there is no more data, leaves your buffer intact, and sets the eof bit. The only strange thing is that the buffer remains holding the same value between loop iterations. I'm guessing that your compiler found a simple optimization to make, and did not reallocate the buffer every iteration through your loop, like it is in your code. Just an efficiency thing, but it's best to put things like that, where you're allocating an object or array, outside the loop so they don't get done every time through. Anyway, I digress. Try this:
    char buffer[HPGL_TOOL_MAX_LINE_LENGTH+1];
    dataFile.getline(buffer, HPGL_TOOL_MAX_LINE_LENGTH);

    while(!(dataFile.eof() || dataFile.bad() || dataFile.fail()))
    {
    // If we're in here, then we know we got good data last time
    cout << "buffer = " << buffer << endl;

    // Add to the part list

    partNameList.push_back(buffer);

    // Get the next set of data, but make sure it's good before we do anything with it
    dataFile.getline(buffer, HPGL_TOOL_MAX_LINE_LENGTH);
    }
    This should work fine, I think. If I'm totally off, someone please correct me, it's entirely possible that I am.

  5. #5
    Join Date
    May 2001
    Posts
    153
    Thanks for your replies.

    I am using windows 2000 with VC++ 6.0, and hpux 10.20 with aCC compiler.

    Bob, I tried the algorithm that you provided, and it works fine on both OSs.

    Thanks much!

    Kamran

  6. #6
    Join Date
    May 2001
    Posts
    153
    Actually, still not working!

    The above algorithm works for unix, but now reads one line less on windows!

    Axter, I tried your suggestion, works on unix, but fails on windows, here's the code

    Code:
    while(!(dataFile.eof() || dataFile.bad() || dataFile.fail()))
    {
        string buffer; // string is already using the std namespace
    
        #ifdef _MSC_VER
            std::getline(dataFile, buffer);
        #else
            getline(dataFile, buffer);
        #endif
    
    
        if (buffer.size() <= 0)
            continue;
                
        // Add to the part list
        partNameList.push_back(buffer);
    
    }
    It works on unix, but get compile error on windows as follows:

    error C2780: 'class std::basic_istream<_E,_Tr> &__cdecl std::getline(class std::basic_istream<_E,_Tr> &,class std::basic_string<_E,_Tr,_A> &,const _E)' : expects 3 arguments - 2 provided
    D:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\string(149) : see declaration of 'getline'

    I tried with 3 arguments

    std::getline(dataFile, buffer, ' ');

    Still compile error:

    error C2784: 'class std::basic_istream<_E,_Tr> &__cdecl std::getline(class std::basic_istream<_E,_Tr> &,class std::basic_string<_E,_Tr,_A> &,const _E)' : could not deduce template argument for 'class std::ba
    sic_istream<_E,_Tr> &' from 'class ifstream'

  7. #7
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    The following worked under :
    • Windows/VC++
    • Irix/GNU g++
    • Linux/pgCC (Portland Group C++ compiler)


    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	ifstream infile("input.txt");
    	if (!infile)
    	{
    		cout << "Problem openning file" << endl;
    		return 1;
    	}
    
    	string buffer;
    
    	while (getline(infile,buffer))
    	{
    		cout << buffer << endl;
    	}
    
    	return 0;
    
    }

  8. #8
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    I've tried your original code on Visual Studio 6.0 SP5, gcc 3.0, gcc 3.0.4, and gcc 3.1. I don't think there's a problem with your original code and I'd guess your aCC compiler has "issues". Try to download gcc; it's open-source, but you'll probably have to build it yourself, as there don't seem to be too many 10.20 binaries out there. If you're going to build 3.1, I suggest you get 2.95.2 and build that first; I was unable to build 3.1 out of the box on our hp 10.20 system. Also, make sure you read the platform-specific configuration notes; you'll need gnu's binutils assembler and gnu's make and everything to install it. I'd test your code on aCC myself, but I don't have it on our 10.20 system.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured