Что произойдет, если fopen
выйдет из строя? Я вижу некоторые неинициализированные указатели
плавать в этом случае. И в маловероятном случае, что malloc
терпит неудачу, вы будете иметь несколько нулевых указателей, которые не должны быть
разыменовываются. И вы не убедитесь, что по крайней мере две строки были
на самом деле читать, прежде чем делать цикл в main
; если бы не было, ты
собираюсь попытаться вывести неинициализированные данные. Не говоря уже о том, что
Вы никогда не освобождаете память, которую выделяете.
(FWIW: используя вашу стратегию, j
должен быть публичным, но fp
может быть локальным
до FileReader::FileReader
.)
Почти точным эквивалентом этого будет использование:
std::vector<std::vector<char> > lines;
// ...
FileReader( char const* path )
: lines( 56000, std::vector<char>( 1440 ) )
{
// ...
}
Единственная разница будет в вызове fgets
, который должен быть
fgets( &lines[j][0], lines[j].size(), fp )
.
Возможно, я бы предпочел использовать инициализированный std::vector<std::string>
пусто, а затем выполняется откат для каждой строки:
FileReader( char const* path )
{
std::ifstream input( path );
std::string line;
while ( std::getline( input, line ) ) {
lines.push_back( line + '\n' );
}
}
Гораздо проще, и решает большинство проблем, с которыми вы сталкиваетесь.
(На практике я, вероятно, проверю, правильно ли был открыт файл
по отдельности; как правило, приятно вывести сообщение об ошибке, если вы не можете
откройте вход, а не рассматривайте его как пустой файл.)
И, конечно, нет смысла использовать new
в main
. Просто:
int
main()
{
FileReader file( "D:/testfile.txt" );
for ( size_t i = 0; i != file.lines.size(); ++ i ) {
std::cout << file.lines[i];
}
return std::cout.flush() ? EXIT_SUCCESS : EXIT_FAILURE;
}