每当我将varible声明为char并将其扫描为字符串“%s”时,我的输出控制台崩溃。这是代码
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
char a[20];
int i;
printf("Enter a name ");
scanf("%s",&a);
for(i=0;i<strlen(a);i++)
{
a[i] = toupper(a[i]);
i++;
printf("%s\n",toupper(a[i]));
}
return 0;
}
答案 0 :(得分:2)
i++;
循环体内的第二个for
可能导致索引逐个指向,printf("%s\n",toupper(a[i]));
将超出绑定访问权限undefined behavior
您可以从循环体内删除i++
。
接下来,toupper(a[i])
返回int
,这对%s
格式说明符无效,后者再次调用UB。
那就是说,
为防止缓冲区溢出过长输入,最好用scanf()
限制输入长度,
您不需要传递数组的地址,只需数组名就足够了
总的来说,你应该写
scanf("%19s",a);
答案 1 :(得分:1)
您在使用toupper
并打印的循环中遇到两个问题。
首先,你在循环中增加变量i
两次。
第二个问题是printf
:
printf("%s\n",toupper(a[i]));
在这里你要求printf
打印一个字符串,但作为参数你给它一个字符(实际上是int
,toupper
返回int
)。使用"%c"
格式说明符打印单个字符。
顺便说一下,打印时不需要调用toupper
,因为之前的作业,角色应该已经是大写字母。
答案 2 :(得分:0)
您的打印循环错误,并且给您未定义的行为:
printf("%s\n",toupper(a[i]));
正在将toupper(a[i])
传递给printf()
的{{1}}格式说明符,这需要%s
而不是普通char *
。这会触发未定义的行为。
逐个打印每个字符没有意义,而是将整个字符串转换为大写字母,然后打印一次:
char
有时需要for(i = 0; a[i] != '\0'; ++i)
{
a[i] = (char) toupper((unsigned char) a[i]);
}
printf("%s\n", a);
左右的转换,因为它需要并返回toupper()
,并且您希望在转换为/从字符转换时要小心。
请注意,我将对int
的调用考虑在内,这可能有点“太聪明”,但这就是我希望编写代码的方式。如果我们要循环遍历字符,则无需单独计算长度。