【问题标题】:strcat not behaving as desiredstrcat 未按预期运行
【发布时间】:2017-03-11 02:47:11
【问题描述】:

我正在尝试编写一个程序,该程序需要用户输入两次,然后将结果连接起来,但我遇到了问题。

我的预期输出是:

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 调用之间清除缓冲区中的剩余元素而不将剩余元素读入“垃圾”数组?

这是我正在使用的代码:

#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 的返回值,为简洁起见,我将其省略了。

【问题讨论】:

  • strcat 将一个字符串附加到另一个字符串。但是您使用未初始化的参数缓冲区调用它。

标签: c undefined-behavior fgets strcat


【解决方案1】:

你的问题是

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() 在输入流上给出未定义的行为。

【讨论】:

    【解决方案2】:

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

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

    或者,您可以使用sprintf

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

    【讨论】:

      猜你喜欢
      • 2014-11-12
      • 1970-01-01
      • 2020-06-28
      • 2012-02-18
      • 2018-01-18
      • 2012-06-14
      • 2019-03-03
      • 2012-09-21
      • 2014-07-19
      相关资源
      最近更新 更多