【问题标题】:Strange output of the C program using toupper function使用 toupper 函数的 C 程序的奇怪输出
【发布时间】:2016-07-04 12:12:57
【问题描述】:

这是我的程序,将从标准输入中输入的所有字母大写。但是有些输出很奇怪。例如,如果输入是“lorem ipsum”,输出将是“LOREM IPSUMS?”。如果输入是单个字符,例如“m”,则输出将为“MZ#X?” . “S?”和“Z#X?”不应该在这里,但它们会附加到输出中。

为什么会这样?

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

int main(void){
        char input;
        char upper[100];
        int count = 0;

        while((input = getchar())){
                if(input == '\n')
                        break;
                if(input >= 'a' && input <= 'z')
                        input = toupper(input);
                *(upper + count) = input;
                count++;
        }

        printf("%s\n", upper);

        return 0;
}

【问题讨论】:

  • 你没有空终止你的字符串。
  • C 中的字符串需要一个结束标记才能正确打印。
  • 另外值得注意的是getchar() 在文件末尾返回 EOF(包括终端输入,如果在那里完成)。因此,如果没有换行符(例如从具有单个非换行符终止的字符串的文件重定向或有人在终端键盘上按 ctrlz/d),这将永远循环。不确定裁决者会有多严格,但您可能想解决这个问题。

标签: c toupper


【解决方案1】:

您可能希望将数组中的所有元素设置为 0 (ASCII NUL),因为我们不知道 upper 数组中的内容。

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

int main(void){
    char input;
    char upper[100];
    int count = 0;

    memset(upper, 0, 100);

    while((input = getchar())){
            if(input == '\n')
                    break;
            if(input >= 'a' && input <= 'z')
                    input = toupper(input);
            *(upper + count) = input;
            count++;
    }

    printf("%s\n", upper);

    return 0;
}

如果你不确定 memset 是做什么的,你可以用 for 循环来做。

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

int main(void){
    char input;
    char upper[100];
    int count = 0;

    for (int i = 0; i < 100; i++) {
       upper[i] = 0;
    }

    while((input = getchar())){
            if(input == '\n')
                    break;
            if(input >= 'a' && input <= 'z')
                    input = toupper(input);
            *(upper + count) = input;
            count++;
    }

    printf("%s\n", upper);

    return 0;
}

【讨论】:

  • 实际使用或需要 count 吗?
  • 有什么理由在while循环之后使用upper[count] = 0;而不是在只有one时使用nullchar爆炸内存区域必需,你已经知道它属于哪里
  • OP 使用 count 来索引 upper 数组。
  • 卖掉那 99 个 '0' 字节以获得好钱。其中一个效果很好;)
  • @WhozCraig,正是我的想法。对该评论 +1。将 EVERYTHING 设为 null 是没有意义的。这只是 CPU 上不必要的处理操作。
【解决方案2】:

您的代码对我有用。 唯一的事情,但这是意料之中的,你会在字符串之后得到垃圾,因为你的 char 数组的长度为 100。你应该在字符串的末尾放一个 0 来告诉 printf 你的字符串在那里结束。放

*(upper + count) = 0;

就在 printf 之前。

【讨论】:

    【解决方案3】:

    您的代码有一些问题:

    • NULL 终止符未添加到字符串的末尾。
    • 没有对超出分配数组范围的索引进行任何检查。
    • 用户可以在没有换行符的情况下中断输入,使程序永远循环。
    • getchar 返回一个 int。

    你可以试试这个修复:

    #include <stdio.h>
    #include <ctype.h>
    
    const int MAX_CHAR = 101;
    
    int main() {
        int input;
        char upper[MAX_CHAR];
        int count = 0;
    
        while( count < MAX_CHAR - 1 ) {
            input = getchar();
            if ( input == EOF  || input == '\n' ||  input == '\r' )
                break;
            if ( input >= 'a' && input <= 'z' )
                input = toupper(input);
            upper[count] = input;
            count++;
        }
        // add the null terminator
        upper[count] = '\0';
    
        printf("%s\n", upper);
    
        return 0;
    }
    

    【讨论】:

    • 谢谢。真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 2014-02-04
    • 2020-05-14
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    相关资源
    最近更新 更多