Как найти количество символов в файле без обхода содержимого - PullRequest
7 голосов
/ 03 февраля 2012

В проекте мне нужно прочитать файл, и мне нужно работать с количеством символов в файле, и есть ли способ получить количество символов, не читая его символ за символом (в противном случае мне придется прочитайте файл дважды, один раз, чтобы узнать количество символов в нем).

Возможно ли это вообще?

Ответы [ 5 ]

11 голосов
/ 03 февраля 2012

Да.

Искать до конца получить позицию конца, который является размером.

FILE*  file = fopen("Plop");
fseek(file, 0, SEEK_END);
size_t  size = ftell(file);      // This is the size of the file.
                                 // But note it is in bytes.
                                 // Also note if you are reading it into memory this is
                                 // is the value you want unless you plan to dynamically
                                 // convert the character encoding as you read.

fseek(file, 0, SEEK_SET);        // Move the position back to the start.

В C ++ поток имеет одинаковую функциональность:

std::ifstream   file("Plop");
file.seekg(0, std::ios_base::end);
size_t size = file.tellg();

file.seekg(0, std::ios_base::beg);
8 голосов
/ 03 февраля 2012

Вы можете попробовать это:

FILE *fp = ... /*open as usual*/;
fseek(fp, 0L, SEEK_END);
size_t fileSize = ftell(fp);

Однако, это возвращает количество байтов в файле, а не количество символов . Это не то же самое, если известно, что кодировка составляет один байт на символ (например, ASCII).

Вам нужно будет «перемотать» файл обратно в начало после того, как вы узнаете размер:

fseek(fp, 0L, SEEK_SET);
2 голосов
/ 03 февраля 2012

Простой ответ - нет. Точнее, это зависит от системы: под Unix, это возможно (например, используя stat); под виндой это не возможно для текстового файла, но если вы читаете файл в двоичном виде, есть функция GetFileSize, которую можно использовать.

Хотя это и не гарантируется, для всех известных мне реализаций (для эти две платформы), ища до конца файла, затем делать ftell, вернет что-то, что при преобразовании в достаточно большой целочисленный тип, даст те же результаты, что и выше (с те же ограничения).

Наконец: зачем вам эта информация? Если это просто выделить буфер соответствующего размера, даже с текстовым файлом, GetFileSizetell после поиска до конца) вернет значение немного больше чем количество байтов, которые вы можете прочитать. Твой буфер будет слегка слишком большой, но обычно это не проблема.

1 голос
/ 03 февраля 2012

Вверху моей головы, так что взгляните на размер файла и разделите его на количество байтов одного символа?

Проблемы возникают при работе с пробелами, концами и т. Д.

1 голос
/ 03 февраля 2012

Я думаю, что вы, вероятно, ищете решение для динамической памяти . На самом деле вы спросили: «Есть ли способ получить количество символов в файле, не читая его?». Ответ (при условии, что один байт на символ) - да, вы можете использовать вызов stat, чтобы получить размер файла, а размер файла в байтах - это количество символов. С UTF-8 ответ - нет, но давайте отложим это на мгновение, так как начинающие компьютерные ученые обычно не беспокоятся об интернационализации.

Я думаю, что причина, по которой вы хотите знать, сколько символов в нем, - чтобы у вас было достаточно места для хранения их всех. Вам не нужно знать, насколько велик файл для хранения всего этого.

Если у вас есть std::vector<char>, он может вначале содержать десять символов, затем вырасти до двадцати, затем десяти тысяч ... И когда вы закончите читать файл, он будет содержать их всех, даже хотя ты никогда не знал, сколько их будет.

...