【问题标题】:How to have a function output a string, not just the first word如何让函数输出字符串,而不仅仅是第一个单词
【发布时间】:2021-12-31 15:47:19
【问题描述】:

我正在编写一个函数来将字符串中的每个小写字符大写。它从用户那里获取一个字符串,这是函数的输入。如果用户不输入空格,我的程序可以工作,但是当字符串中有空格时,函数结束。

#include <stdio.h>

char *uppercase(char *c) {
    int i = 0;
    while (c[i] != '\0') {
        if (123 > c[i] && c[i] > 96)
            c[i] = c[i] - 'a' + 'A';
        i++;
    }
    return c;
}

int main() {
    char input[100];
    printf("Enter the phrase: ");
    scanf("%s", input);
    printf("%s", uppercase(input));
    return 0;
}

例子:

输入:test test
输出:TEST

输入:Hello
输出:HELLO

输入:How are you
输出:HOW

我认为这与while 声明有关?感谢您的帮助。

【问题讨论】:

标签: c scanf c-strings fgets capitalize


【解决方案1】:

问题不在于while 语句,而在于scanf() 格式:%s 从输入中读取一个单词,将行的其余部分留在stdin 缓冲区中。另请注意,键入超过 99 个字符的单词将导致未定义的行为,因为scanf() 将写入超出input 数组的末尾。使用%99s 可以避免这个问题,但不能解决您的问题。

您应该使用fgets()stdin 读取整行输入。

此外,您应该使用字符常量,例如 'a''z'&lt;ctype.h&gt; 中的函数,而不是使用硬编码的 ASCII 值。

这是一个使用 ASCII 的修改版本:

#include <stdio.h>

char *uppercase(char *s) {
    int i = 0;
    while (s[i] != '\0') { 
        if (s[i] >= 'a' && s[i] <= 'z')
            s[i] = s[i] - 'a' + 'A';
        i++;
    }
    return s;
}

int main() {
    char input[100];
    printf("Enter the phrase: ");
    if (fgets(input, sizeof input, stdin)) {
        fputs(uppercase(input), stdout);
    }
    return 0;
}

这是一个使用&lt;ctype.h&gt;的更便携的:

#include <ctype.h>
#include <stdio.h>

char *uppercase(char *s) {
    int i = 0;
    unsigned char c;
    while ((c = s[i]) != '\0') {
        if (islower(c))
            s[i] = toupper(c);
        i++;
    }
    return s;
}

这可以进一步简化为可以为从0UCHAR_MAX 的所有字节值调用toupper()

#include <ctype.h>
#include <stdio.h>

char *uppercase(char *s) {
    for (size_t i = 0; s[i] != '\0'; i++) {
        s[i] = toupper((unsigned char)c);
    }
    return s;
}

【讨论】:

    【解决方案2】:

    任意使用

    scanf ("%99[^\n]", input);
    

    fgets( input, sizeof( input ), stdin );
    

    此外,使用 123 或 96 之类的幻数也是一种不好的做法

    if (123 > c[i] && c[i] > 96)
    

    如果您至少会编写代码,代码将更具可读性

    if ( 'a' <= c[i] && c[i] <= 'z' )
    

    除了while循环,最好使用for循环

    for ( char *p = c; *p; ++p )
    {
        if ( 'a' <= *p && *p <= 'z' )
        {
            *p = *p - 'a' + 'A'; 
        } 
    }
    

    【讨论】:

    • scanf("%99[^\n]", input);fgets(input, sizeof(input), stdin); 在明显和更微妙的方面表现不同:scanf() 将在 stdin 缓冲区中保留换行符,如果用户输入,则将失败并返回 0一个空行。
    • @chqrlie 还有什么?这如何阻止使用其中任何一个功能?
    • 它没有,但我的意思是警告 OP 这些不明显的陷阱。
    猜你喜欢
    • 2019-11-05
    • 2020-05-06
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    相关资源
    最近更新 更多