strcat 未按预期运行

strcat not behaving as desired

我正在尝试编写一个接受用户输入两次,然后连接结果的程序,但我 运行 遇到了问题。

我的预期输出是:

What would you like your message to be? input
message received: input

What would you like your message to be? words
message received: words

new message: inputwords

相反,我收到的是乱码响应。

收到输出:

What would you like your message to be? input
message received: input

What would you like your second message to be? words
message received: words

new message: ??s?inputwords

第一个问题:

如何正确连接这两个字符串?

另外:

由于每条消息我只接受 5 个字符的输入,我将如何清除这些 fgets 调用之间缓冲区中的剩余元素而不将剩余元素读入 "garbage" 数组?

这是我使用的代码:

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


int main() {

    char message[6];
    char garbage[9999];
    char message2[6];

    printf("\nWhat would you like your message to be? ");
    fgets(message, 6, stdin);

    printf("message received: %s\n", message);

    fgets(garbage, 9999, stdin); //this is gross

    printf("\nWhat would you like your second message to be? ");
    fgets(message2, 6, stdin);

    printf("message received: %s\n", message2);

    fgets(garbage, 9999, stdin); //still gross

    char newString[25];
    strcat(newString, message);
    strcat(newString, message2);

    printf("new message: %s\n", newString);
    return 0;

}

注意:我知道我应该捕捉 fgets 的 return 值,为简洁起见,我将其省略。

strcat 需要一个以 null 结尾的字符串,而您的缓冲区未初始化。将对 strcat 的第一次调用替换为对 strcpy:

的调用
char newString[25];
strcpy(newString, message);
strcat(newString, message2);

或者,您可以使用 sprintf:

char newString[25];
sprintf(newString, "%s%s", message, message2);

你的问题是

char newString[25];
strcat(newString, message);
strcat(newString, message2);

strcat() 假定第一个参数已使用以 nul 结尾的字符串初始化。第一次调用提供了一个未初始化的数组,因此具有未定义的行为。要修复,只需将第一个调用更改为 strcpy() - 这会将 message 复制到 newString,而不依赖 newString 被初始化。

要刷新一行输入(即读取直到文件末尾、读取错误或遇到换行符),一种常见的技术是

int c; 
while ((c = fgetc(stdin)) != '\n' && c != EOF) { }

然而,将面向字符的输入(如 fgets())与面向字符的输入(如 fgetc())混合通常被认为不是一个好主意,因为两者处理换行符等事情的方式不同。

另一种使用fgets()的方法是

char buffer[2];
while (fgets(buffer, sizeof buffer, stdin) != NULL && buffer[0] != '\n') {}

需要使用缓冲区(第一种形式为整数c,第二种形式为buffer)。这两个选项最小化所需缓冲区的大小(使用 fgetc()sizeof int 或使用 fgets()2

有些人建议使用 fflush(stdin)。这是个坏主意——根据 C 标准,fflush() 在输入流上给出未定义的行为。