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 );
}
Run Code Online (Sandbox Code Playgroud)
我在stackoverflow上的另一个线程中询问了有关此代码的另一个问题,但不想在那个上加倍 - 为什么终止零被添加到fgets读入的这些文件的末尾?fgets无论如何都会增加终止零点,这不是太过分了吗?
fgets 将 nul 终止符写入您提供的缓冲区中(如果您将缓冲区大小指定为大于 0)。否则,您无法对其调用 strlen(),strlen() 需要一个字符串,如果它不是 nul 终止,那么它就不是一个字符串。
你问的是
line[ strlen( line ) - 1 ] = '\0';
Run Code Online (Sandbox Code Playgroud)
这会删除 . 中的最后一个字符line。如果您读了一行,它会替换最后一个字符,可能是带有 nul 终止符的 \n 。
考虑 fgets 只是读取一行,例如您的line缓冲区现在包含字符串“Hello\n”(\n 只是这里的转义序列,它实际上只是 1 个字符,而不是 2 个)
strlen("Hello\n")为6,6-1为5,所以5.索引被0替换
"Hello\n"
^
|
Add 0 terminator
Run Code Online (Sandbox Code Playgroud)
结果:“你好”
请小心:
line如果 fgets 失败并且没有向缓冲区写入任何内容,您不想四处查看。