使用带有%s
格式说明符的scanf
将仅读取单个单词.如果你想读一整行由几个单词组成的单词(例如"Linus Torvalds\n"
),那么我建议你用fgets
代替.然而,关于混合fgets
和scanf
,要注意this problem.此外,有关如何从fgets
输入中删除换行符的信息,请参阅this question.我建议您根本不使用scanf
作为用户输入,而是始终使用fgets
.
条件if("Linus Torvalds\n")
没有意义,因为该条件将始终为真.如果要比较name
和"Linus Torvalds\n"
的内容,则需要使用strcmp
函数.
还有,这条线
if (strcmp("n", yesno)){
这是错误的,因为函数strcmp
要求它的两个参数都是一个指针,每个参数都指向一个字符串,即指向以空字符结尾的字符序列.然而,yesno
不是指针.&yesno
也是错误的,因为这样的指针将只指向单个字符,而不是指向以空字符结尾的字符序列.
如果两个字符串匹配,函数strcmp
将返回零,如果不匹配,则返回非零值.因此,您可能希望将返回值strcmp
与零进行比较.
我建议你这样重写你的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void get_line_from_user( const char prompt[], char buffer[], int buffer_size );
int main( void )
{
char input[200];
get_line_from_user(
"Hello adventurer, are you here to learn Linux? (y/n) ",
input, sizeof input
);
if ( strcmp( input, "y" ) == 0 )
{
get_line_from_user(
"Great! What is your name? ",
input, sizeof input
);
if ( strcmp( input, "Linus Torvalds" ) == 0 )
{
printf( "Achievement complete: In God We Trust\n" );
printf( "Nice to meet you! My name is Richard Stallman.\n" );
}
else
{
printf( "Nice to meet you! My name is Linus Torvalds.\n" );
}
}
else if ( strcmp( input, "n" ) == 0 )
{
printf( "Ok! Bye!" );
}
else
{
printf( "That's not an answer.\n" );
}
}
//This function will read exactly one line of input from the
//user. It will remove the newline character, if it exists. If
//the line is too long to fit in the buffer, then the function
//will automatically reprompt the user for input. On failure,
//the function will never return, but will print an error
//message and call "exit" instead.
void get_line_from_user( const char prompt[], char buffer[], int buffer_size )
{
for (;;) //infinite loop, equivalent to while(1)
{
char *p;
//prompt user for input
fputs( prompt, stdout );
//attempt to read one line of input
if ( fgets( buffer, buffer_size, stdin ) == NULL )
{
printf( "Error reading from input!\n" );
exit( EXIT_FAILURE );
}
//attempt to find newline character
p = strchr( buffer, '\n' );
//make sure that entire line was read in (i.e. that
//the buffer was not too small to store the entire line)
if ( p == NULL )
{
int c;
//a missing newline character is ok if the next
//character is a newline character or if we have
//reached end-of-file (for example if the input is
//being piped from a file or if the user enters
//end-of-file in the terminal itself)
if ( (c=getchar()) != '\n' && !feof(stdin) )
{
if ( c == EOF )
{
printf( "Error reading from input!\n" );
exit( EXIT_FAILURE );
}
printf( "Input was too long to fit in buffer!\n" );
//discard remainder of line
do
{
c = getchar();
if ( c == EOF )
{
//this error message will be printed if either
//a stream error or an unexpected end-of-file
//is encountered
printf( "Error reading from input!\n" );
exit( EXIT_FAILURE );
}
} while ( c != '\n' );
//reprompt user for input by restarting loop
continue;
}
}
else
{
//remove newline character by overwriting it with
//null character
*p = '\0';
}
//input was ok, so break out of loop
break;
}
}
该程序具有以下行为:
Hello adventurer, are you here to learn Linux? (y/n) y
Great! What is your name? Jimmy
Nice to meet you! My name is Linus Torvalds.
Hello adventurer, are you here to learn Linux? (y/n) y
Great! What is your name? Linus Torvalds
Achievement complete: In God We Trust
Nice to meet you! My name is Richard Stallman.
Hello adventurer, are you here to learn Linux? (y/n) n
Ok! Bye!
Hello adventurer, are you here to learn Linux? (y/n) sdfsdgf
That's not an answer.