我正在编写一个小程序,输入由3个字母组成的国家名称和该国在奥运会上获得的奖牌数量,除非输入"结束"一词,否则该程序将一直要求输入。我写了一段时间的循环来做这件事,但我似乎无法停止
//Program calculate the winner of olympics based on metal input
#include<stdio.h>
#include<string.h>
int main (void)
{
int maxMedals=0, tempGold=0, tempSilver=0, tempBronze=0,tempSum;
char country[3];
char winner[3];
printf("no o o O L Y M P I C o o o");
printf("n o o S C O R E S o on");
printf("Enter country code, # gold, # silver, # bronzen");
while ((strcmp(country,"end"))!=0)
{
printf("==>");
scanf("%s %d %d %d",&country, &tempGold, &tempSilver, &tempBronze);
tempSum=tempGold+tempSilver+tempBronze;
if (maxMedals<tempSum)
{
maxMedals = tempSum;
strcpy(winner, country);
// printf("n %s", winner);
}
else
{
maxMedals=maxMedals;
}
}
printf("nwe reached heren");
printf("nWinner is %s with %d medalsn", country, maxMedals);
return 0;
}
问题是country
只有3个字符长。在C中,scanf
写入一个十六进制0字符来指示字符串的末尾,而strcmp
则对一直到十六进制0的字符串进行比较(至少在字符串不同之前),因此"end"
至少需要4个字符。
如果只有3的空间,并且写入3+十六进制0,则会溢出到未知内存中,导致未定义的行为。通过在我的机器上打印country
,它打印"endend"
,这意味着winner
在内存中似乎直接在country
之后,所以它打印这两个,因为printf
也一直持续到它找到十六进制0,但是,由于这是未定义的行为,所以不能保证这种行为,并且在不同的编译器上可能会有所不同。
尝试使其成为4个字符:
char country[4];
此外,您的循环不正确-您仍然处理"end"
,因为您只在处理后检查它。
处理这个问题的两种方法:
- 在
scanf
后面放一个if语句,检查"end"是否为break
- 在while循环的前面放一个
scanf
,在while环路的末尾放一个(所以有两个相同的scanf
)
scanf("%s",&country);
if (strcmp(country,"end") == 0)
break;
scanf("%d %d %d", &tempGold, &tempSilver, &tempBronze);
希望这个改变能奏效。首先,您获得国家的输入,如果不是end
,则继续获取其他选项。即使在一行中输入了四个参数,这也会起作用。
您可以按如下方式中断scanf
。。因此,当您输入"end
"时,您将退出while
。
scanf("%s",country);
if(strcmp(country,"end")==0)
break;
scanf("%d %d %d",&tempGold, &tempSilver, &tempBronze);
您在输入之前将country
与"end"进行比较,当您输入end 1 1 1
时,程序将停止。但是您的代码可能会导致缓冲区溢出,因为country
和winner
被声明为char country[3];
char winner[3];
,C中的字符串最后需要一个额外的