следующий предложенный код:
- безупречная компиляция
- выполняет желаемую функциональность
- правильно проверяет ошибки
- выводит пользовательские сообщения об ошибках в
stderr
- выводит текстовую причину, по которой система считает, что произошла ошибка, в
stderr
- документах, почему каждый заголовочный файл включен
- показывает пример того, как обрабатыватьслучай, когда пользователю не удалось ввести параметр командной строки (в данном случае имя входного файла)
- использует
size_t
вместо int
при передаче параметров в malloc()
и realloc()
и теперь предложенный код:
#include <stdio.h> // fopen(), perror(), fclose() fprintf()
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc(), realloc(). free()
int main( int argc, char *argv[] )
{
if( argc != 2 )
{
fprintf( stderr, "USAGE: %s <fileName>\n", argv[0] );
exit( EXIT_FAILURE );
}
FILE * file = fopen( argv[1], "r" );
if( !file )
{
perror( "fopen failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
int ch;
char * line = malloc( 10 );
if( !line )
{
perror( "malloc failed" );
fclose( file ); // cleanup
exit( EXIT_FAILURE );
}
// implied else, malloc successful
size_t lineLen = 10;
size_t i = 0;
while( (ch = fgetc(file)) != EOF )
{
if( ch == '\n' )
{
line[i] = '\0';
// do something with contents of line
i = 0;
}
else
{
if(i >= lineLen )
{
lineLen *= 2;
char * temp = realloc( line, lineLen );
if( !temp )
{
perror( "realloc failed" );
// cleanup
fclose( file );
free( line );
exit( EXIT_FAILURE );
}
line = temp;
}
line[i] = (char)ch;
i++;
}
}
free(line);
fclose(file);
}