You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带空格字符串的大小写转换与完整输出问题排查

带空格字符串大小写转换问题:原因与修复方案

问题原因

当前代码无法处理带空格的输入,核心问题出在输入读取环节:

  • 使用scanf("%s", &user_input)读取输入时,%s格式符会自动将**空白字符(空格、换行、制表符)**作为字符串的结束标记,因此只会读取第一个空格之前的内容(比如输入STACK OVERFLOW时,仅STACK被存入user_input,后续的 OVERFLOW完全没被读取)。
  • 转换函数里的空格判断逻辑根本没有机会执行,因为输入的空格根本没被存入数组,自然无法处理。

另外,原代码的循环逻辑存在隐患:for (int i = 0; i <= MAX_CHAR; i++)会遍历到数组的第50个元素(超出了MAX_CHAR定义的数组下标范围,合法下标应为0到49),可能导致越界访问。

修复方案

方案1:使用fgets读取整行输入(推荐)

fgets可以读取包含空格的整行输入,直到遇到换行符或达到指定长度。需要注意的是fgets会把换行符\n也读入字符串,因此需要手动去除。

修改后的完整代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_CHAR 50
char to_lowercase(char letter);
char to_uppercase(char letter);

int main(void)
{
    char user_input[MAX_CHAR];

    printf("Enter a string: ");
    // 读取整行输入,最多读取MAX_CHAR-1个字符(留位置存结束符)
    if (fgets(user_input, MAX_CHAR, stdin) == NULL) {
        printf("Failed to read input!");
        exit(EXIT_FAILURE);
    }

    // 去除fgets读取到的换行符(如果存在)
    size_t len = strlen(user_input);
    if (len > 0 && user_input[len-1] == '\n') {
        user_input[len-1] = '\0';
    }

    // 遍历字符串直到结束符
    for (int i = 0; user_input[i] != '\0'; i++)
    {
        printf("%c", to_lowercase(user_input[i]));
    }
    printf("\n");

    return EXIT_SUCCESS;
}

char to_lowercase(char letter)
{
    if ((letter >= 'a') && (letter <= 'z')) {return letter;} 
    else if ((letter >= 'A') && (letter <= 'Z')) {return letter + 32;}
    else if (letter == ' ') {return letter;}
    else
    {
        printf("Not a valid character!");
        exit(EXIT_FAILURE);
    }
}

char to_uppercase(char letter)
{
    if ((letter >= 'A') && (letter <= 'Z')) {return letter;}
    else if((letter >= 'a') && (letter <= 'z')) {return letter - 32;}
    else if (letter == ' ') {return letter;}
    else
    {
        printf("Not a valid character!");
        exit(EXIT_FAILURE);
    }
}

方案2:修改scanf格式符

如果坚持使用scanf,可以使用%[^\n]格式符,它表示读取所有字符直到遇到换行符为止。但需要限制读取长度,避免缓冲区溢出:

// 替换原scanf行
scanf("%49[^\n]", user_input);

注:49是因为数组长度为50,要留1个位置给字符串结束符\0。这种方法不会读取换行符,但如果输入开头就是换行符,会导致读取失败,因此fgets是更稳妥的选择。

此外,原循环的i <= MAX_CHAR改为user_input[i] != '\0',只遍历到字符串实际结束的位置,避免越界访问。同时,把ASCII码值替换为字符常量(比如'a'、' '),代码可读性更强。

内容的提问来源于stack exchange,提问作者user23569449

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:36:01