CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jul 2007
    Posts
    33

    seekg() not working?

    I don't really know what the cause of this problem is, but I've definitely encountered the same problem before.

    In the code, on line 71, where I've presumed the origin of the problem to be, there is the code "image.seekg(init); cout<<image.tellg();" The only reason that I added cout<<image.tellg(); was to verify that there is a problem here. The problem is that image.tellg() always returns -1 even though the value of init is always 19. I don't know why this problem exists: There used to be no problem with this line of code before I made a few changes elsewhere in the program. It's as though the rules of C++ change every time I make a small change to my program.

    Anyways, attached is ABC.txt, and the code for the program is as follows...

    Code:
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<fstream>
    using namespace std;
    
    int w,h,maxval,start,init,begy,endy,begx,endx;
    char temp[5];
    
    void cp(int a)
         {cout<<"checkpoint "<<a<<"\n";
         system("PAUSE");}
    
    void cleartemp()
         {int a;
         for(a=0; a<5; a++)temp[a]='\0';}
    
    int main()
        {cleartemp(); //identifies width, height, and maxval values
        ifstream image("ABC.txt");
        image.seekg(0);
        image.ignore(5,' ');
        image.getline(temp,5,' ');
        w=atoi(temp);
        cleartemp();
        image.getline(temp,5,' ');
        h=atoi(temp);
        cleartemp();
        image.getline(temp,5,'\n');
        maxval=atoi(temp);
        cleartemp();
        image.seekg(1,ios::cur);
        init=image.tellg();
        int x,y,a,b;
        ofstream abc("ABCanalysis.txt");
        start=0;
        int count=0;
        do
            {begx=begy=endx=endy=0;
            for(y=(int)(start/w); y<h; y++) //establishes a vertical starting point for character analysis
                     {if(y==h-1){begy=-1; break;}
                     if(begy>0)break;
                     for(x=start; x<w; x++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); begy=y+start; break;}}}
            if(begy==-1){cout<<begy<<" "; cp(2); break;}
            for(y=begy+1; y<h; y++) //establishes a vertical end point for character analysis
                     {if(endy>0)break;
                     for(x=start; x<w; x++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); break;}
                              if(x==w-1 && atoi(temp)==maxval){cleartemp(); endy=y+1; break;}}}
            for(x=start; x<w; x++) //establishes a horizontal starting point for character analysis
                     {if(x==w-1){begx=-1; break;}
                     if(begx>0)break;
                     for(y=begy; y<=endy; y++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); begx=x+start; break;}}}
            if(begx==-1)
                        {start=(endy+1)*w;
                        continue;}
            for(x=begx+1; x<w; x++) //establishes a horizontal end point for character analysis
                     {if(endx>0)break;
                     for(y=begy; y<=endy; y++)
                              {image.seekg(init); cout<<image.tellg(); //This is where the problem seems to originate
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); break;}
                              if(y==endy && atoi(temp)==maxval){cleartemp(); endx=x; break;}}}
            b=0;
            for(x=begx; x<=endx; x++)
                        {image.seekg(init);
                        for(a=0; a<start+x; a++)image.ignore(5,' ');
                        for(y=begy; y<=endy; y++)
                                    {image.getline(temp,5,' ');
                                    b=b+atoi(temp);
                                    cleartemp();
                                    if(y!=endy)for(a=0; a<w; a++)image.ignore(5,' ');
                                    else break;}
                        b=1-(b/(255*(endx-begx)));
                        abc.put(' ');
                        itoa(b,temp,10);
                        abc.write(temp,strlen(temp));
                        cleartemp();}
            b=0;
            for(y=begy; y<=endy; y++)
                        {image.seekg(init);
                        for(a=0; a<start+(y*w); a++)image.ignore(5,' ');
                        for(x=begx; x<=endx; x++)
                                    {image.getline(temp,5,' ');
                                    b=b+atoi(temp);
                                    cleartemp();}
                        b=1-(b/(255*(endy-begy)));
                        abc.put(' ');
                        itoa(b,temp,10);
                        abc.write(temp,strlen(temp));
                        cleartemp();}
            start=start+(endx-begx);
            count=count+1;
            cout<<count<<"\n";}while(begy!=-1);
        abc.close();
        image.close();
        return 1;}
    Attached Files Attached Files

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: seekg() not working?

    Quote Originally Posted by hixidom
    I don't really know what the cause of this problem is, but I've definitely encountered the same problem before.
    Why are you using functions such as seekg() on a file that was opened in text mode? You should open the file as a binary file (ios::binary).

    When you open a file in text mode, the run-time will translate carriage return/line feeds, causing functions such as seekg(), tellg(), and other functions that require exact byte locations in the file to not work reliably. To add, text mode also processes control characters within the file differently than in binary mode. For example, an ASCII 26 is an EOF in a text file, and processing stops dead right there once an EOF is encountered.

    If indeed your file is an image file, it should be opened in binary mode, not text mode, where there is no translation going on behind the scenes, and the characters in the file are read/written as exactly as you specify. Then functions such as seekg() are reliable.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jul 2007
    Posts
    33

    Re: seekg() not working?

    Perhaps opening ABC.txt as a binary file will help in other ways, but it still did not solve my problem: image.tellg() still returns -1 every time.

    Regardless, thanks for the suggestion. I did modify my program according to your advice, changing "ifstream image("ABC.txt");" to "ifstream image("ABC.txt", ios::binary);"

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: seekg() not working?

    First, your code is very hard to read using that type of formatting. Here is a better formatted version:
    Code:
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<fstream>
    using namespace std;
    
    int w, h, maxval, start, init, begy, endy, begx, endx;
    char temp[5];
    
    void cp( int a )
    {
        cout << "checkpoint " << a << "\n";
        system("PAUSE");
    }
    
    void cleartemp()
    {
        int a;
    
        for ( a = 0; a < 5; a++ )
            temp[a] = '\0';
    }
    
    int main()
    {
        cleartemp(); //identifies width, height, and maxval values
        ifstream image("q:\\ABC.txt");
        image.seekg(0);
        image.ignore(5, ' ');
        image.getline(temp, 5, ' ');
        w = atoi(temp);
        cleartemp();
        image.getline(temp, 5, ' ');
        h = atoi(temp);
        cleartemp();
        image.getline(temp, 5, '\n');
        maxval = atoi(temp);
        cleartemp();
        image.seekg(1, ios::cur);
        init = image.tellg();
        int x, y, a, b;
        ofstream abc("ABCanalysis.txt");
        start = 0;
        int count = 0;
    
        do
        {
            begx = begy = endx = endy = 0;
    
            for ( y = (int)(start / w); y < h; y++ ) //establishes a vertical starting point for character analysis
            {
                if( y == h - 1 )
                {
                    begy = -1;
                    break;
                }
    
                if( begy > 0 )
                    break;
    
                for ( x = start; x < w; x++ )
                {
                    image.seekg(init);
    
                    for ( a = 0; a < (y * w) + x; a++ )
                        image.ignore(5, ' ');
                    image.getline(temp, 5, ' ');
    
                    if( atoi(temp) != maxval )
                    {
                        cleartemp();
                        begy = y + start;
                        break;
                    }
                }
            }
    
            if( begy == -1 )
            {
                cout << begy << " ";
                cp(2);
                break;
            }
    
            for ( y = begy + 1; y < h; y++ ) //establishes a vertical end point for character analysis
            {
                if( endy > 0 )
                    break;
    
                for ( x = start; x < w; x++ )
                {
                    image.seekg(init);
    
                    for ( a = 0; a < (y * w) + x; a++ )
                        image.ignore(5, ' ');
                    image.getline(temp, 5, ' ');
    
                    if( atoi(temp) != maxval )
                    {
                        cleartemp();
                        break;
                    }
    
                    if( x == w - 1 && atoi(temp) == maxval )
                    {
                        cleartemp();
                        endy = y + 1;
                        break;
                    }
                }
            }
    
            for ( x = start; x < w; x++ ) //establishes a horizontal starting point for character analysis
            {
                if( x == w - 1 )
                {
                    begx = -1;
                    break;
                }
    
                if( begx > 0 )
                    break;
    
                for ( y = begy; y <= endy; y++ )
                {
                    image.seekg(init);
    
                    for ( a = 0; a < (y * w) + x; a++ )
                        image.ignore(5, ' ');
                    image.getline(temp, 5, ' ');
    
                    if( atoi(temp) != maxval )
                    {
                        cleartemp();
                        begx = x + start;
                        break;
                    }
                }
            }
    
            if( begx == -1 )
            {
                start = (endy + 1) * w;
                continue;
            }
    
            for ( x = begx + 1; x < w; x++ ) //establishes a horizontal end point for character analysis
            {
                if( endx > 0 )
                    break;
    
                for ( y = begy; y <= endy; y++ )
                {
                    image.seekg(init);
                    cout << image.tellg(); //This is where the problem seems to originate
    
                    for ( a = 0; a < (y * w) + x; a++ )
                        image.ignore(5, ' ');
                    image.getline(temp, 5, ' ');
    
                    if( atoi(temp) != maxval )
                    {
                        cleartemp();
                        break;
                    }
    
                    if( y == endy && atoi(temp) == maxval )
                    {
                        cleartemp();
                        endx = x;
                        break;
                    }
                }
            }
            b = 0;
    
            for ( x = begx; x <= endx; x++ )
            {
                image.seekg(init);
    
                for ( a = 0; a < start + x; a++ )
                    image.ignore(5, ' ');
    
                for ( y = begy; y <= endy; y++ )
                {
                    image.getline(temp, 5, ' ');
                    b = b + atoi(temp);
                    cleartemp();
    
                    if( y != endy )
                        for ( a = 0; a < w; a++ )
                            image.ignore(5, ' ');
                    else
                        break;
                }
                b = 1 - (b / (255 * (endx - begx)));
                abc.put(' ');
                itoa(b, temp, 10);
                abc.write(temp, strlen(temp));
                cleartemp();
            }
            b = 0;
    
            for ( y = begy; y <= endy; y++ )
            {
                image.seekg(init);
    
                for ( a = 0; a < start + (y *w); a++ )
                    image.ignore(5, ' ');
    
                for ( x = begx; x <= endx; x++ )
                {
                    image.getline(temp, 5, ' ');
                    b = b + atoi(temp);
                    cleartemp();
                }
                b = 1 - (b / (255 * (endy - begy)));
                abc.put(' ');
                itoa(b, temp, 10);
                abc.write(temp, strlen(temp));
                cleartemp();
            }
            start = start + (endx - begx);
            count = count + 1;
            cout << count << "\n";
        } while ( begy != -1 );
        abc.close();
        image.close();
        return 1;
    }
    Second, your code does absolutely no checking. It assumes that everything is OK, when obviously it isn't.

    For example, you don't check to see if the file name was opened. You also don't check to see if any of those seekg() calls uses values that fall out of bounds of the file. You don't check any of those variables you're using to compute offsets in the file. You also have this superfluous cast:
    Code:
            for ( y = (int)(start / w); y < h; y++ ) //establishes a vertical starting point for character analysis
    All of those values are int, so dividing an int by an int gives you an int (start / w), not a double or anything like that.

    What probably is happening is that you've messed up the file stream before you call tellg(), and tellg() is reporting back to you that you've damaged the stream in some way.

    Place sanity checks in your code, then possibly that will tell you what you're doing wrong. There are also functions in the stream class that tells you if the stream is valid or not. The blame is not C++, but in the way you've written your program in terms of nothing is checked for valid values, especially the state of the stream is never checked.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Jul 2007
    Posts
    33

    Re: seekg() not working?

    Using lines such as cout<<image.tellg() is the only means of code checking that I am familiar with. Otherwise, I just try to make sure that I set the loop parameters in the program in such a way that they never exceed the size of my file. I really don't know anything about how "throw", "catch", "this", etc. are used in a C++ program. Sorry.

    Anyways, something that I changed has allowed the line, image.seekg(init), to work. So the following occurance of image.tellg() returns 18 now. However, when I moved that occurance of image.tellg() down such that it follows for(a=0; a<(y*w)+x; a++)image.ignore(4,' '); it now returns -1 in the first iteration of the given "for" loop, leading me to believe that image.ignore(4,' ') is somehow not functioning as planned.

    When I say that I have problems with C++, it is this kind of problem that I am referring to, where modifying the syntax of one function, in order to fix it, causes another function to exhibit undesired behaviors.

    Here's the updated code

    Code:
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<fstream>
    using namespace std;
    
    int w,h,maxval,start,init,begy,endy,begx,endx;
    char temp[5];
    
    void cp(int a)
         {cout<<"checkpoint "<<a<<"\n";
         system("PAUSE");}
    
    void cleartemp()
         {int a;
         for(a=0; a<5; a++)temp[a]='\0';}
    
    int main()
        {cleartemp(); //identifies width, height, and maxval values
        ifstream image("ABC.txt", ios::binary);
        image.seekg(0);
        image.ignore(5,' ');
        image.getline(temp,5,' ');
        w=atoi(temp);
        cleartemp();
        image.getline(temp,5,' ');
        h=atoi(temp);
        cleartemp();
        image.getline(temp,5,'\n');
        maxval=atoi(temp);
        cleartemp();
        image.seekg(1,ios::cur);
        init=image.tellg();
        int x,y,a,b;
        ofstream abc("ABCanalysis.txt");
        start=0;
        int count=0;
        do
            {begx=begy=endx=endy=-2;
            for(y=start/w; y<h; y++) //establishes a vertical starting point for character analysis
                     {if(y==h-1){begy=-1; break;}
                     if(begy>=0)break;
                     for(x=start; x<w; x++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); begy=y+start; break;}}}
            if(begy==-1)break;
            for(y=begy+1; y<h; y++) //establishes a vertical end point for character analysis
                     {if(endy>=0)break;
                     for(x=start; x<w; x++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); break;}
                              if(x==w-1 && atoi(temp)==maxval){cleartemp(); endy=y+1; break;}}}
            for(x=start; x<w; x++) //establishes a horizontal starting point for character analysis
                     {if(begx>=0)break;
                     if(x==w-1){begx=-1; break;}
                     for(y=begy; y<=endy; y++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++)image.ignore(5,' ');
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); begx=x+start; break;}}}
            if(begx==-1)
                        {start=(endy+1)*w;
                        continue;}
            for(x=begx+1; x<w; x++) //establishes a horizontal end point for character analysis
                     {if(endx>=0)break;
                     for(y=begy; y<=endy; y++)
                              {image.seekg(init);
                              for(a=0; a<(y*w)+x; a++){image.ignore(4,' ');cout<<image.tellg();}
                              image.getline(temp,5,' ');
                              if(atoi(temp)!=maxval){cleartemp(); break;}
                              if(y==endy && atoi(temp)==maxval){cleartemp(); endx=x; break;}}}
            b=0;
            for(x=begx; x<=endx; x++)
                        {image.seekg(init);
                        for(a=0; a<start+x; a++)image.ignore(5,' ');
                        for(y=begy; y<=endy; y++)
                                    {image.getline(temp,5,' ');
                                    b=b+atoi(temp);
                                    cleartemp();
                                    if(y!=endy)for(a=0; a<w; a++)image.ignore(5,' ');
                                    else break;}
                        b=1-(b/(255*(endx-begx)));
                        abc.put(' ');
                        itoa(b,temp,10);
                        abc.write(temp,strlen(temp));
                        cleartemp();}
            b=0;
            for(y=begy; y<=endy; y++)
                        {image.seekg(init);
                        for(a=0; a<start+(y*w); a++)image.ignore(5,' ');
                        for(x=begx; x<=endx; x++)
                                    {image.getline(temp,5,' ');
                                    b=b+atoi(temp);
                                    cleartemp();}
                        b=1-(b/(255*(endy-begy)));
                        abc.put(' ');
                        itoa(b,temp,10);
                        abc.write(temp,strlen(temp));
                        cleartemp();}
            start=start+(endx-begx);
            count=count+1;
            cout<<count<<"\n";}while(begy!=-1);
        abc.close();
        image.close();
        return 1;}

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: seekg() not working?

    Quote Originally Posted by hixidom
    Using lines such as cout<<image.tellg() is the only means of code checking that I am familiar with.
    That is not what I'm referring to when I say "check". I'm referring to actually doing programming so that the code does something if there is a failure anywhere. What good will cout do if your code doesn't do something if there is a failure?

    For example, if you checked the state of the stream, at the point the tellg() is done, you will see that the stream is already in a bad state.
    Otherwise, I just try to make sure that I set the loop parameters in the program in such a way that they never exceed the size of my file.
    And how do you do that? When I run your program, the eof() bit is set as well as the fail bit on the stream where you call "seekg()". So obviously your code does not do this. To verify this for you, call image.eof(), and you will get true returned to you. At some point, that eof() bit is set -- where it is set is what you should be trying to figure out.

    If you have a debugger, please use the debugger (or learn to use it). Your loops definitely do not prevent hitting the EOF, as the bit is set. As a matter of fact, I highly doubt you can get anything like your program actually working correctly in any reasonable time without using a debugger.
    I really don't know anything about how "throw", "catch", "this", etc. are used in a C++ program. Sorry.
    But you still aren't using the functions that test the state of a stream, as I mentioned above.

    This loop is executed 16,080 times when I run it on my machine:
    Code:
    for ( a = 0; a < (y * w) + x; a++ )
           image.ignore(5, ' ');
    Is that what you expected? By that time, the getline() is called after this, the image.fail() bit is set. So it is set within that loop.
    Anyways, something that I changed has allowed the line, image.seekg(init), to work. So the following occurance of image.tellg() returns 18 now. However, when I moved that occurance of image.tellg() down such that it follows for(a=0; a<(y*w)+x; a++)image.ignore(4,' '); it now returns -1 in the first iteration of the given "for" loop,
    That is because you've exectued ignore(5, ' ') over 16,000 times!
    When I say that I have problems with C++, it is this kind of problem that I am referring to, where modifying the syntax of one function, in order to fix it, causes another function to exhibit undesired behaviors.
    You didn't modify the syntax of any function. All you did was change your code around, so of course you're changing the behaviour of the program when you do that.

    The issue that I see is that you don't really know what your program was doing -- did you know about the loop executing so many times? If you used a debugger, you should see that your program was at fault, and it has nothing to do with C++ changing things. If C++ changed things as you claimed, how could anyone write a correct program?

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Jul 2007
    Posts
    33

    Re: seekg() not working?

    If C++ changed things as you claimed, how could anyone write a correct program?
    (I'm amazed when I actually pull it off myself)

    Anyways, you seemed to be stuck on the fact that the following loop runs 16,080 times:
    Code:
    for ( a = 0; a < (y * w) + x; a++ )
           image.ignore(5, ' ');
    Am I aware of this? Of course I am. There are exactly 16,080 pixels in the image being analyzed (ABC.pgm a.k.a. ABC.txt). Sure I don't run any checks in my programs, but that's only because I'm very precise in writing them. If the problem in question was a problem that I was familiar with, I would not need any help in solving it, but that is clearly not the case. I understand that checks may be able to help me find the cause of a problem in a program that I have written incorrectly, however, the program is written to the best of my knowledge regarding C++. Therefore, even if I were familiar with using failure checks in my programs, I would still not have the knowledge required to recognize the existing problem.

    The fact that the line
    Code:
     {image.seekg(init);
    results in the location of the file pointer being undefined still baffles me. Does the seekg() function not work that way? I tried using
    Code:
    image.seekg(init, ios::beg)
    instead, but that did not solve anything.

    Thank you.
    Andy

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: seekg() not working?

    Quote Originally Posted by hixidom
    (I'm amazed when I actually pull it off myself)

    Anyways, you seemed to be stuck on the fact that the following loop runs 16,080 times:
    Code:
    for ( a = 0; a < (y * w) + x; a++ )
           image.ignore(5, ' ');
    That is where the fail bit is set. You are advancing the file pointer way beyond the size of the file.
    Am I aware of this? Of course I am. There are exactly 16,080 pixels in the image being analyzed (ABC.pgm a.k.a. ABC.txt).
    Pixels are not bytes. The first argument to the ignore() function is the number of bytes to ignore, not the number of pixels. Multiply 16,000 * 5. That is where the file pointer is after the loop. Is your file over 80K in size?
    Sure I don't run any checks in my programs, but that's only because I'm very precise in writing them.
    Then why is your program crashing if you're very precise in writing? Seriously, no programmer is precise in writing anything but a very trivial program. Making claims such as "I'm very precise" is not valid, as no programmer is precise.

    Do you have a function reference to fstream? If so, does it mention the different bits from std::ios that are set? If so, a simple test of the fail() or eof() bit in that loop should have been obvious that something is wrong with that loop. Then you would have discovered that ignore() advances by bytes, then, etc. etc.

    What I'm saying is that placing checks will tell you where the failure occurs. Then when you isolate when the failure actually occurred, then you take the next step to figure out why the failure occurs. Your current code has no checks for anything -- it assumes that everything is OK. When things are not OK, it is then the time to place checks in the code, not only to figure out errors, but to make the program more bulletproof if bad data, a missing file, etc. is encountered.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; August 28th, 2008 at 12:25 PM.

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: seekg() not working?

    Quote Originally Posted by hixidom
    The fact that the line
    Code:
     {image.seekg(init);
    results in the location of the file pointer being undefined still baffles me.
    I'll say it again:

    The fail bit is already set when you call seekg(). That's why it doesn't work. The stream is bad by the time seekg() is called, because you've messed it up in the loop I showed you.

    There is nothing wrong with seekg(). It is doing what it's supposed to do, and that is report failure if the stream is in a failed state.

    Regards,

    Paul McKenzie

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