奇怪的字符串附加在printf上

时间:2017-08-21 19:18:32

标签: c string

我写了一个简单的程序来切换字符串,我在我的电脑和IDEOne中试过,我收到一个附加到输出的奇怪字符串。我错过了什么吗?

#include <stdio.h>

int main (int argc, char *argv[]) {
    char input[100], output[100];
    int length;
    scanf("%s", input);

    length = sizeof(input)/sizeof(input[0]);

    for (int i = 0; input[i] != '\0'; i++) {
        if (input[i] >= 97 && input[i] <= 122) {
            output[i] = input[i] - 32;
        } else if (input[i] >= 65 && input[i] <= 90) {
            output[i] = input[i] + 32;
        }
    }

    printf("%s\n", output);
    return 0;
}

enter image description here

指向IDEOne的链接 - https://ideone.com/NFlDJK

4 个答案:

答案 0 :(得分:2)

%s期望以null结尾的字符串作为参数。您必须在'\0'的末尾追加output个字符。

答案 1 :(得分:2)

您不会终止output,即您没有写出标记字符串结尾的最终\0字符。因此,printf,它期望一个0终止的字符串,可能会打印一些垃圾。一个简单的解决方案是将output定义为

char output[100] = { 0 };

因此,output将填充\0,之前您写的任何内容都会找到结束。

正如评论中所指出的,代码中还有一些问题可能导致未定义的行为或意外的结果。

首先,如果输入超过99个字符(然后产生未定义的行为),您将获得缓冲区溢出。您可以使用scanf("%99s", input)来避免这种情况。

其次,如果您的输入包含一些不触发切换表达式的字符,则可能会出现意外的短暂结果。在您的代码中,output将在相关位置包含垃圾;在output = { 0 } - 变体中,结果将在此时“结束”。因此,"abc1234DEF"之类的输入可能分别产生"ABC?@:-def""ABC"。添加else { output[i]=input[i]; }以克服此问题。

第三,length = sizeof(input)/sizeof(input[0])将始终返回100,无论输入的实际字符数是多少。请注意,sizeof(input)100sizeof(input[0])1作为编译时常量。要根据输入的字符数获得字符串的“长度”,请使用strlen(input)

int main (int argc, char *argv[]) {
    char input[100], output[100] = { 0 };
    scanf("%99s", input);

    size_t length = strlen(input);

    for (int i = 0; i < length; i++) {
        if (input[i] >= 97 && input[i] <= 122) {
            output[i] = input[i] - 32;
        } else if (input[i] >= 65 && input[i] <= 90) {
            output[i] = input[i] + 32;
        }
        else {
            output[i] = input[i];
        }
    }

    printf("%s\n", output);
    return 0;
}

答案 2 :(得分:0)

问题的答案是:

output []数组必须以NUL(0x00)终止。 &#39;%s&#34;调用printf()时的格式说明符在遇到NUL之前不会停止输出字节。

由于发布的代码未能设置所需的NUL字节,因此&#34;%s&#34;将继续输出字节,直到它发生在某个随机NUL字节上。 这是未定义的行为,可能导致seg故障事件。

您可以通过以下方式解决问题: 在for()代码块之后和printf()语句之前,插入语句:

output[i] = '\0';

答案 3 :(得分:-2)

在你的循环之后,我还有一个,你只需要放

输出[I] =&#39; \ 0&#39 ;;

完成了