struct DVDInfo *ReadStruct( void ) {
struct DVDInfo *infoPtr;
int num;
char line[ kMaxLineLength ];
char *result;
infoPtr = malloc( sizeof( struct DVDInfo ) );
if ( NULL == infoPtr ) {
printf( "Out of memory!!! Goodbye!\n" );
exit( 0 );
}
printf( "Enter DVD Title: " );
result = fgets( line, kMaxLineLength, stdin );
line[ strlen( line ) - 1 ] = '\0';
infoPtr->title = MallocAndCopy( line );
printf( "Enter DVD comment: " );
result = fgets( line, kMaxLineLength, stdin );
line[ strlen( line ) - 1 ] = '\0';
infoPtr->comment = MallocAndCopy( line );
do {
printf( "Enter DVD Rating (1-10): " );
scanf( "%d", &num );
Flush();
}
while ( ( num < 1 ) || ( num > 10 ) );
infoPtr->rating = num;
printf( "\n----------\n" );
return( infoPtr );
}
我在stackoverflow上的另一个线程中询问了有关此代码的另一个问题,但是不想在那个上加倍 - 为什么终止零被添加到fgets读入的这些文件的末尾? fgets无论如何都会添加终止零点,这不是太过分了吗?
答案 0 :(得分:3)
通常,您使用NUL字符替换fgets添加到字符串的换行符。在所有情况下,fgets将NUL终止。
请参阅:http://www.opengroup.org/onlinepubs/009695399/functions/fgets.html
答案 1 :(得分:2)
fgets将nul终止符写入您提供的缓冲区(如果指定缓冲区大小大于0)。否则你不能在它上面调用strlen(),strlen()需要一个字符串,如果它不是nul终止它不是一个字符串。
你问的是
line[ strlen( line ) - 1 ] = '\0';
这会删除line
中的最后一个字符。如果你读了一行,它会替换最后一个字符,可能是一个带有nul终结符的\ n。
考虑fgets只读一行,例如你的line
缓冲区现在包含字符串“Hello \ n”(\ n这里只是转义序列,它实际上只有1个字符,而不是2)
strlen(“Hello \ n”)是6,而6-1是5,所以5.索引被0替换
"Hello\n"
^
|
Add 0 terminator
结果: “你好”
小心点:
line
中找到它,并且没有向你的缓冲区写任何东西。答案 2 :(得分:1)
您
result = fgets( line, kMaxLineLength, stdin );
没关系,因为行的大小是kMaxLineLength
。
fgets
最多从size
读取一个少于stream
个字符并将其存储到缓冲区中...
答案 3 :(得分:1)
line[ strlen( line ) - 1 ] = '\0';
是不必要的(如果字符串尚未以字符结尾,那么不安全 - strlen()
将无法正常工作)。 fgets()
将终止缓冲区。此外,在尝试复制result != NULL
之前,您应该检查line
。 fgets()
在文件结尾或发生错误时返回NULL。
答案 4 :(得分:1)
是的,这太过分了。
一个建议,使其更强大,以防止代码腐烂......改变
result = fgets( line, kMaxLineLength, stdin );
到
result = fgets( line, sizeof(line), stdin );