【问题标题】:Why is this reverse string program not working?为什么这个反向字符串程序不起作用?
【发布时间】:2017-07-23 19:03:51
【问题描述】:

我是 C 编程的新手,所以请原谅我的天真。以下程序在输出时无法将输入字符串的最后一个字符打印为输出字符串的第一个字符。

例如:

Enter no. of elements: 5
Enter string: hello
The reversed string is: lleh

为什么o 不打印?

#include <stdio.h>

int main() {
    printf("Enter no. of elements: ");
    int n;
    scanf("%d", &n);
    char string[10000];
    printf("Enter string: ");
    for (int i = 0; i < n; i++) {
        scanf("%c", &string[i]);
    }
    printf("The reversed string is: ");
    for (int i = (n - 1); i >= 0; i--) {
        printf("%c", string[i]);
    }
    printf("\n");
    return 0;
}

【问题讨论】:

    标签: c


    【解决方案1】:

    有一个副作用你要注意:

    • scanf("%d", &amp;n); 之后,输入流缓冲区中有一个挂起的换行符。

    • 当您稍后输入 n 字符时,scanf("%c", &amp;string[i]) 首先读取挂起的换行符,然后是您输入的 n-1 的第一个字符,其余的输入将保留在输入缓冲区中。

    scanf() 是一个非常笨重的函数。很难正确使用。

    以下是解决问题的方法:

    #include <stdio.h>
    
    int main() {
        char string[10000];
        int i, n, c;
    
        printf("Enter no. of elements: ");
        if (scanf("%d", &n) != 1 || n < 0 || n > 10000)
            return 1;
    
        // read and discard pending input
        while ((c = getchar()) != '\n' && c != EOF)
            continue;
    
        printf("Enter string: ");
        for (i = 0; i < n; i++) {
            if (scanf("%c", &string[i]) != 1)
                break;
        }
        // the above loop could be replaced with a single call to fread:
        // i = fread(string, 1, n, stdin);
    
        printf("The reversed string is: ");
        while (i-- > 0) {
            printf("%c", string[i]);
        }
        printf("\n");
        return 0;
    }
    

    【讨论】:

    • 您还应该注意最大数量的 scanf 字符,这会导致缓冲区溢出。使用例如scanf("%99999[^\n]", string); 设置上限。
    • 或者改用fgets
    • @TomKuschel:scanf("%99999[^\n]", string) 会在第一个换行处停止,如果用户立即输入换行符,甚至会失败。限制应为9999 而不是99999。 OP 想要读取 n 字符,getchar()scanf("%c", ...fread() 似乎更好。
    • @chqrlie:以上评论适用于您的行if (scanf("%c", &amp;string[i]) != 1)。当用户输入超过 10,000 个字符时会发生什么?是的,9999 而不是 99999(这是一个错字),你是对的。
    • @TomKuschel:如果用户输入超过 10000 个字符,程序将只读取第一个 n,在初始步骤中验证它在 0..10000 范围内。剩余的字符将保留在输入缓冲区或终端缓冲区中。
    【解决方案2】:

    您的scanf() 应该以空格开头(more info about that)。这是代码:

    #include <stdio.h>
    
    int main() {
        printf("Enter no. of elements: ");
        int n;
        scanf(" %d", &n);
        char string[10000];
        printf("Enter string: ");
        for (int i = 0; i < n; i++) {
            scanf(" %c", &string[i]);
        }
        /* Just to be safer. */
        string[n] = '\0';
        printf("The reversed string is: ");
        for (int i = (n-1); i >= 0; i--) {
            printf("%c", string[i]);
        }
        printf("\n");
        return 0;
    }
    

    【讨论】:

    • 这是一个更简单的解决方案,但它不允许输入包含空格
    • @chqrlie 他不是要这个,在这种情况下可能没有必要。
    • 他在问为什么hello 中的o 没有被打印出来……下一个测试是hello world ;-)
    • @BetaRunner 是的,这解决了问题。但是你能解释一下那个空间是什么意思吗?
    • @user5250644:不,在"%d" 后面添加一个空格会打开另一个蠕虫罐:scanf 将继续读取输入,直到在数字后面输入一个非空白字符。
    【解决方案3】:

    向格式字符串添加空格使scanf 能够使用 每次按下时都会发生的输入中的换行符 返回。如果没有空格,string[i] 将收到 字符'\n'

    因此,在第 11 行的格式说明符 %c 之前只放置了一个空格。 scanf(" %c", &amp;string[i]);

    【讨论】:

      猜你喜欢
      • 2020-07-04
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-01-26
      • 2013-01-26
      • 2016-04-20
      • 2013-09-10
      • 1970-01-01
      相关资源
      最近更新 更多