我是C的新人,我被困住了。我想写一个简单的程序,它将从键盘输入并输出它,如果它不是一个'退出'字。我尝试了几种不同的方法,但没有一种方法可行。几乎在所有情况下,我都得到第一个输入的无限输出。
以下是我的方法之一:
#include <stdio.h>
int main() {
char word[80];
while (1) {
puts("Enter a string: ");
scanf("%79[^\n]", word);
if (word == "exit")
break;
printf("You have typed %s", word);
}
return 0;
}
我想在完成每个循环后它应该再次给我提示,但事实并非如此。 我做错了什么。
如果你知道请给我一些建议。
提前致谢。真的,如果你帮助我理解我做错了什么,我会很高兴的。
哦,顺便说一句,我注意到当我输入一些单词并按'Enter'时,结果字符串最后也包含Enter
。我怎么能摆脱这个?
答案 0 :(得分:3)
不正确的字符串比较 - 使用strcmp()
。
if (word == "exit")
只是比较2地址:char
中第一个word
的地址和字符串文字char
中第一个"exit"
的地址。代码需要比较从这些地址开始的内容:strcmp()
这样做。
上一行的输入中的剩余'\n'
。添加scanf()
格式的空格以使用可选的前导空格。同时检查scanf()
结果。
scanf()
,"%d"
和"%u"
之类的 "%f"
说明符本身会使用可选的前导空格。 3个例外:"%c"
,"%n"
和"%["
。
在'\n'
格式末尾添加printf()
。 @Matt McNabb
#include <stdio.h>
int main() {
char word[80];
while (1) {
puts("Enter a string: ");
// v space added here
if (scanf(" %79[^\n]", word) != 1)
break; // Nothing saved into word or EOF or I/O Error
if (strcmp(word, "exit") == 0)
break;
printf("You have typed %s\n", word);
}
return 0;
}
很好,OP在scanf()
答案 1 :(得分:2)
哦,顺便说一下,当我输入一些单词并按“输入”时,结果字符串最后也包含Enter键。我怎么能摆脱这个?
这是因为您不能在printf("You have typed %s", word);
之后输出换行符。执行的下一个语句是puts("Enter a string: ");
。所以你会看到You have typed helloEnter a string:
。要解决此问题,请更改为printf("You have typed %s\n", word);
正如其他人所提到的,使用strcmp
来比较C中的字符串。
最后,scanf格式字符串"%79[^\n]"
与换行符不匹配。因此输入流仍包含换行符。下次到达此声明时,换行符仍在流中,但由于您明确排除了换行符,因此它仍然不匹配。
在获得下一行之前,您需要丢弃该换行符(以及该行的任何其他输入)。一种方法是将输入更改为scanf("%79[^\n]%*[^\n]", word); getchar();
,这意味着:
最后检查scanf
的返回值是个好主意,这样如果出现错误,你可以退出程序而不是进入无限循环。
答案 2 :(得分:2)
如果下一个字符是换行符([^\n]
),而不读取换行符,则说明符scanf
将中止\n
。因此,第一个之后的scanf
调用将不会读取任何输入。
如果您想阅读单个单词,请使用%79s
说明符和以下代码删除字符串末尾的\n
:
if(word[strlen(word)]=='\n')
word[strlen(word)]='\0';
如果要读取整行,可以通过以下方式从输入缓冲区中删除换行符:
char line[80];
int i;
while(1)
{
puts("Enter a string:");
i=-1;
scanf("%79[^\n]%n",line,&i);
//%n returns the number of characters read so far by the scanf call
//if scanf encounters a newline, it will abort and won't modify i
if(i==-1)
getchar(); //removes the newline from the input buffer
if(strcmp(line,"exit")==0)
break;
printf("You have typed %s\n",line);
}
return 0;
答案 3 :(得分:1)
在阅读内存缓冲区之前,最好使用memset(3)清除(以获得可重现的内容),并且应使用strcmp(3)来比较字符串。另外,请考虑在输入之前使用fflush(3)(即使在您的情况下实际上不需要),也不要忘记测试scanf(3)的结果,以及大多数printf(3)格式控制字符串的结果应以\n
结束 - 以冲洗结束 - 所以:
#include <stdio.h>
int main() {
char word[80];
while(1) {
puts("Enter a string: ");
memset (word, 0, sizeof(word)); // not strictly necessary
fflush(stdout); // not strictly necessary
if (scanf("%79[^\n]", word)<=0) exit(EXIT_FAILURE);
if (!strcmp(word,"exit"))
break;
printf("You have typed %s\n", word);
};
return 0;
}
我建议用fgets(3)阅读整行并删除其结尾换行符(使用strchr(3))。另请阅读getline(3)
不要忘记编译所有警告和调试信息(例如gcc -Wall -g
)并学习如何使用调试器(例如gdb
)
答案 4 :(得分:0)
您的第一个问题是您无法将字符串与'=='进行比较。所以:
if (word == "exit")
应该是
if ( strncmp( word, "exit", 4 ) == 0 )
(如果你知道这个词是零终止的,那么你也可以使用strncmp( word, "exit", strlen(word) )
,并且可以安全地使用不良值。还有其他一些选项。)
你的第二个问题是scanf()没有消耗输入,可能是因为它与你所说的预期不匹配。以下是如何做你想做的事情的一个很好的解释: