代码块输出控制台已停止工作

Code blocks output console has stopped working

每当我将变量声明为 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;
}

for 循环体内的第二个 i++; 可能会导致索引指向偏移一个,然后 printf("%s\n",toupper(a[i])); 将超出调用 [=19 的绑定访问=].

您可以从循环体内删除 i++

接下来,toupper(a[i]) returns 一个 int,它对 %s 格式说明符无效,它再次调用 UB。

也就是说,

  • 为防止输入过长造成缓冲区溢出,最好用scanf()

  • 限制输入长度
  • 不需要传数组地址,传数组名即可

所以,总的来说,你应该写

scanf("%19s",a);

在使用 toupper 和打印的循环中有两个问题。

首先是在循环中将变量 i 增加两次

第二个问题是printf:

printf("%s\n",toupper(a[i]));

在这里你要求 printf 打印一个字符串,但是你给它一个字符作为参数(实际上是一个 int, toupper returns 一个 int).使用 "%c" 格式说明符打印单个字符。

顺便说一句,打印时不需要调用 toupper,因为字符应该已经是大写的,因为之前的赋值。

您的打印循环行为不当并给您未定义的行为:

printf("%s\n",toupper(a[i]));

toupper(a[i]) 传递给 printf()%s 格式说明符,这需要 char * 而不是普通的 char。这会触发未定义的行为。

没有必要一个一个地打印每个字符,而是将整个字符串转换为大写,然后打印一次:

for(i = 0; a[i] != '[=11=]'; ++i)
{
    a[i] = (char) toupper((unsigned char) a[i]);
}
printf("%s\n", a);

有时需要围绕 toupper() 进行强制转换,因为它需要 returns int,并且在转换 to/from 字符时要小心一些。

请注意,我排除了对 strlen() 的调用,这可能有点 "too clever" 但这是我希望编写此代码的方式。如果我们要遍历字符,则无需单独计算长度。