首页 > 解决方案 > 程序以错误的方式打印字符串。字符串

问题描述

在我输入姓名和姓氏(例如:姓名:Mario姓氏:)Rossi作为输出而不是得到Mario Rossi我得到ossi Rossi但我不明白为什么。

int main() {
    char space[] = " ";
    char name[40], surname[40], space_name[40], space_surname[40];
    printf("what's your name");
    scanf("%[^\n]", &name);

    printf("Whats your surname");
    scanf(" %[^\n]", &surname);

    strcpy(space_surname, strcat(space, surname));
    strcat(name, space_surname);
    printf("%s", name);
}

标签: cc-stringsstrcpystrcat

解决方案


在您的代码中,您首先在 with 末尾连接,surname它具有未定义的行为,因为只有 2 个元素,一个空格和一个空终止符。最后的复制会破坏数组,您会观察到该数组。这种行为是未定义的,它在您的体系结构上以这种方式发生,但未定义的行为可能会产生其他后果,包括没有可见的影响或计算机崩溃。spacestrcat(space, surname)spacesurnamenamenameossi

另请注意以下备注:

  • 您应该告诉scanf()要存储的最大字符数,namesurname避免在输入过长时出现未定义的行为。
  • 你应该通过name而不是&name.
  • 您应该测试 的返回值scanf()以避免无效输入的未定义行为,例如在文件意外结束或第一个空行的情况下scanf()
  • 您可以定义具有始终定义行为的大小的数组。

对于更简洁的方法,您将使用 2 个不同的数组firstnamesurname用户输入并将名称构造为第三个数组,该数组name对于所有情况都足够大:

strcpy(name, firstname);
strcat(name, " ");
strcat(name, surname);

或可读性较差:

strcat(strcat(strcpy(name, firstname), " "), surname);

以上两种方法都将不必要地遍历已经复制到name. 一个更清洁、更安全的解决方案是使用snprinf()

snprintf(name, sizeof name, "%s %s", firstname, surname);

这是修改后的版本:

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

int main() {
    char firstname[40]; /* up to 39 characters for the first name */
    char surname[40];   /* up to 39 characters for the last name */
    char name[80];      /* 39 chars + 1 space + 39 chars + 1 null terminator */

    printf("What is your name: ");
    if (scanf(" %39[^\n]", name) != 1)
        return 1;

    printf("What is your surname: ");
    if (scanf(" %39[^\n]", surname) != 1)
        return 1;

    /* simpler solution with `snprintf` */
    snprintf(name, sizeof name, "%s %s", firstname, surname);
    printf("%s\n", name);

    return 0;
}

推荐阅读