1

I'm trying to find the length of a file through a long that increases by 1 until the end of the file is reached. It does go to the end of the file, then reads EOF as if it were another value, causing it to become -1. I can't quite figure out how to stop that from happening and get the actual length of the file. Any help would be appreciated!

My code, currently:

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
void input(ofstream&,string &InputStr);
void ErrChek(ifstream&,long&,char&);

int main(int argc, const char * argv[])
{

    char file2[] = "file2.txt";

    ofstream OutFile;
    ifstream InpFile;
    string InputStr;
    char Read;
    int Choice = 0;
    long Last = 0;
    OutFile.open(file2);

    if(OutFile.fail())
    {
        cout << "file named can not be found \n";
        exit(1);
    }
    input(OutFile,InputStr);
    OutFile.close();
    InpFile.open(file2);
    cout << InpFile.tellg() << endl;
    if(InpFile.fail())
    {
        cout << "file named can not be found \n";
        exit(1);
    }
    ErrChek(InpFile,Last,Read);
    InpFile.close();

    return 0;
}

void input(ofstream &OutFile,string &InputStr) //Gets input from user + writes to file
{
    cout << "Please input 1 sentence for use in the file: ";
    getline(cin,InputStr);
    OutFile << InputStr;
}

void ErrChek(ifstream &InpFile,long &Last,char &Read)
{
    while((Last = InpFile.tellg())!=EOF)
    {
        InpFile.seekg(Last,ios::beg);
        InpFile.get();
        Last = InpFile.tellg();
        cout << InpFile.tellg() << endl;
    }
}

The output:

Please input 1 sentence for use in the file: Test Sentence
0
1
2
3
4
5
6
7
8
9
10
11
12
13
-1
Jason C
  • 34,234
  • 12
  • 103
  • 151
Codetographer
  • 31
  • 1
  • 5
  • 3
    http://stackoverflow.com/questions/5840148/how-can-i-get-a-files-size-in-c – Neil Kirk Nov 09 '14 at 23:01
  • long is not the correct type to store the file size. Use `fstream::streampos` – Neil Kirk Nov 09 '14 at 23:02
  • (note that the 0 is the initial position in the file, not part of the ErrChek loop. – Codetographer Nov 09 '14 at 23:07
  • The link provided by Neil above is a very good read, but I disagree with the duplicate votes. Unless this is truly an XY problem (which it may be) I take this question as the OP performing an experiment that is not working correctly, and wondering about his specific experiment, rather than looking for better ways to determine file length. @Crorad correct me if I'm wrong. – Jason C Nov 09 '14 at 23:17
  • 1
    I need the file length for the purpose of reading a string that is input backwards. I don't believe I'm allowed to use vector or stat because i don't think they've been taught about in class. What we've been taught about is the position marker functions (seekg, seekp, tellg, tellp, clear, a few others) and most basic things about fstream. – Codetographer Nov 09 '14 at 23:26
  • 1
    @Crorad In that case, given your limitations, the use of a simple counter as hinted at in [SILENT's answer](http://stackoverflow.com/a/26834419/616460) might also be appropriate for you. – Jason C Nov 09 '14 at 23:38

3 Answers3

1

tellg returns the position of the current character. If it fails, then it returns -1. Going by your example, you could increment a variable while iterating through the stream or use the easier method described in @NeilKirk's link

Community
  • 1
  • 1
SILENT
  • 2,746
  • 1
  • 22
  • 34
1

Your logic is a bit off. tellg() won't return EOF until after a get() at the end of the file. Note that get() would change the file position, but your loop condition is tellg() before the read and you call tellg() again after the read expecting it to be the same as it was before the read - but it won't be.

The fact that there are much cleaner ways to do this aside, if you want to do this using your method, your logic would be something like this (somewhat pseudo-code-y):

Last = 0;

while(InpFile.get()!=EOF)
{
    Last = InpFile.tellg();
}

cout << Last << endl;

Note that your seekg() is unnecessary, as it puts the file pointer in the position it is already in, and I have removed it to simplify.

The key in the above example is you get the file position after you read, but don't overwrite Last when you've hit the EOF. We check the EOF status returned by get rather than by tellg.

Imagine a small 2 or 3 byte file and work through your original code in your head or on paper to get a clearer idea of the logic issues.

Jason C
  • 34,234
  • 12
  • 103
  • 151
0

Maybe it is not the answer you want but why not use stat() instead ? See How do you determine the size of a file in C?

About your code, you would have to output the tellg() value before it is assigned EOF (EOF = -1)

void ErrChek(ifstream &InpFile,long &Last,char &Read)
{
    while((Last = InpFile.tellg())!=EOF)
    {
        cout << Last << endl;
        InpFile.seekg(Last,ios::beg);
        InpFile.get();
    }
}
Community
  • 1
  • 1
Florent
  • 368
  • 1
  • 12