8
\$\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\$
1
  • \$\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, 2016 at 20:18

4 Answers 4

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\$
0
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\$
4
  • \$\begingroup\$ +1 for simplicity, though something in the back of my head says that stat is not portable. \$\endgroup\$ Mar 24, 2011 at 14:38
  • 2
    \$\begingroup\$ Well, stat is defined in POSIX. If that's not portable, I don't know what is. :-P \$\endgroup\$ Mar 25, 2011 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\$ Mar 25, 2011 at 14:29
  • \$\begingroup\$ msdn.microsoft.com/en-us/library/14h5k7ff.aspx \$\endgroup\$
    – Pupsik
    Dec 14, 2015 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\$
5
  • \$\begingroup\$ It does need to be accurate. \$\endgroup\$
    – Maxpm
    Mar 23, 2011 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\$ Mar 23, 2011 at 16:27
  • \$\begingroup\$ The file is opened in binary mode. Encoding doesn't matter. \$\endgroup\$ Mar 23, 2011 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\$ Mar 23, 2011 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\$ Mar 23, 2011 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.