Ответ 1
tellg
не сообщает размер файла, ни смещение
от начала в байтах. Он сообщает значение токена, которое может
позже можно использовать для поиска того же места и не более того.
(Он даже не гарантирует, что вы можете преобразовать тип в
интегральный тип.)
По крайней мере, согласно языковой спецификации: на практике,
в Unix-системах возвращаемое значение будет смещением в байтах
с самого начала файла, а под Windows это будет
смещение от начала файла для файлов, открытых в
двоичный режим. Для Windows (и большинства не-Unix-систем) в тексте
режиме, нет прямого и непосредственного отображения между тем, что
tellg
возвращает и количество байтов, которое вы должны прочитать, чтобы добраться до
это положение. В Windows все, на что вы действительно можете рассчитывать, это
что значение будет не меньше, чем количество байт, которое у вас есть
читать (и в большинстве реальных случаев не будет слишком большим,
хотя это может быть в два раза больше).
Если важно точно знать, сколько байтов вы можете прочитать, единственным способом надежного выполнения этого является чтение. Вы должны быть в состоянии сделать это с чем-то вроде:
file.ignore( std::numeric_limits<std::streamsize>::max() );
std::streamsize length = file.gcount();
file.clear(); // Since ignore will have set eof.
file.seekg( 0, std::ios_base::beg );
Наконец, еще два замечания относительно вашего кода:
Сначала строка:
*buffer = new char[length];
не следует компилировать: вы объявили buffer
как char*
,
поэтому *buffer
имеет тип char
и не является указателем. Учитывая, что
вы, кажется, делаете, вы, вероятно, хотите объявить buffer
как
a char**
. Но гораздо лучшим решением было бы объявить его
как std::vector<char>&
или std::string&
. (Таким образом, вы
также не нужно возвращать размер, и вы не будете утечки памяти
если есть исключение.)
Во-вторых, условие цикла в конце неверно. Если вы действительно хотите читать по одному символу за раз,
while ( file.get( buffer[i] ) ) {
++ i;
}
должен сделать трюк. Лучшее решение, вероятно, было бы читать блоки данных:
while ( file.read( buffer + i, N ) || file.gcount() != 0 ) {
i += file.gcount();
}
или даже:
file.read( buffer, size );
size = file.gcount();
EDIT: я заметил третью ошибку: если вы не открыли
файл, вы не говорите вызывающему. По крайней мере, вы должны
установите size
на 0 (но какая-то более точная ошибка
обработка, вероятно, лучше).