7
\$\begingroup\$

Here's my function for getting the length of a file, in characters:

unsigned int GetFileLength(std::string FileName)
{
std::ifstream InFile(FileName.c_str());
unsigned int FileLength = 0;
while (InFile.get() != EOF) FileLength++; 
InFile.close();
return FileLength;
}

How can this be improved?

\$\endgroup\$
  • \$\begingroup\$ of course you are assuming this is an ASCII file. 1 byte == 1 char. Lets hope there are no foreigners around with their pesky unicode junk :-). Also note the returning uint is a little optimistic in todays world, files get bigger than 4gb \$\endgroup\$ – pm100 Sep 21 '16 at 20:18
7
\$\begingroup\$

Just seek to the end of the file and grab the value:

ifstream is;
is.open (FileName.c_str(), ios::binary );
is.seekg (0, ios::end);
length = is.tellg();
\$\endgroup\$
6
\$\begingroup\$

I dislike seeking, so here's my non-seeking approach.

#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <stdexcept>
#include <string>

off_t GetFileLength(std::string const& filename)
{
    struct stat st;
    if (stat(filename.c_str(), &st) == -1)
        throw std::runtime_error(std::strerror(errno));
    return st.st_size;
}
\$\endgroup\$
  • \$\begingroup\$ +1 for simplicity, though something in the back of my head says that stat is not portable. \$\endgroup\$ – James Schek Mar 24 '11 at 14:38
  • 2
    \$\begingroup\$ Well, stat is defined in POSIX. If that's not portable, I don't know what is. :-P \$\endgroup\$ – Chris Jester-Young Mar 25 '11 at 3:23
  • \$\begingroup\$ @Chris--you're absolutely right! It's not ANSI C, but it's definitely POSIX. And I believe even Windows supports stat. \$\endgroup\$ – James Schek Mar 25 '11 at 14:29
  • \$\begingroup\$ msdn.microsoft.com/en-us/library/14h5k7ff.aspx \$\endgroup\$ – Pupsik Dec 14 '15 at 10:13
1
\$\begingroup\$

Is accuracy important? I believe you could try to get the filesize and divide this by the amount of bytes the formatting uses. This could give a good estimate of the amount of characters in the file.

I say estimate because I might be forgetting about possible headers and such, although I believe a simple text file doesn't have that.

\$\endgroup\$
  • \$\begingroup\$ It does need to be accurate. \$\endgroup\$ – Maxpm Mar 23 '11 at 16:12
  • \$\begingroup\$ Well, considering you can get the exact file size (so not size on disk), as e.g. in the answer of Mark, it should be accurate. Mark's answer assumes single byte encoding. If this is the case, consider it your answer. \$\endgroup\$ – Steven Jeuris Mar 23 '11 at 16:27
  • \$\begingroup\$ The file is opened in binary mode. Encoding doesn't matter. \$\endgroup\$ – Mark Loeser Mar 23 '11 at 18:29
  • 2
    \$\begingroup\$ @Mark Loeser: He wants to get the amount of 'characters' in the file as far as I understand, not the amount of bytes (although that might be the same, yes) \$\endgroup\$ – Steven Jeuris Mar 23 '11 at 20:31
  • \$\begingroup\$ You are right, my mistake. It was pretty early when I looked at this, so yea...I missed the "characters" part :) \$\endgroup\$ – Mark Loeser Mar 23 '11 at 20:48
1
\$\begingroup\$

Try std::ios::ate

#include <fstream>
#include <string>

size_t getFileSize( std::string fileName ) {
    std::ifstream file( fileName, std::ios::binary | std::ios::ate );
    size_t fileSize = file.tellg();
    file.close();

    return fileSize;
}

std::ios::ate opens the file with the pointer(s) at the end. file.eof() would return true.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.