程序以错误的方式打印字符串。 strcpy

问题描述 投票:0回答:1

在我把名字和姓氏的输入(例如:name:Mario surname: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);
}
c string
1个回答
1
投票

strcat(dest, src) 将连接 srcdest. 你的缓冲区 space (长度1不包括null-terminator)不够大,无法容纳两个。另外,你的 space_surname 将会溢出,因为你存储的是一个大小为1的字符串(space) 一个40号的字符串(surname)到一个大小为40的缓冲区。将其至少增加到41大小。有一个 space 字符串也没有必要,因为 space 是字符,可以直接设置。

space_surname[0] = ' ';
space_surname[1] = '\0';  // So you know where to concat to
strcat(space_surname, surname);

请注意,你会遇到同样的问题 name. 你想储存 name (长度40)。space (长度1),和 surname(长度40)都成 name. 你需要创建一个新的 full_name 变量的大小为81或更大,并存储到该变量中。


3
投票

在你的代码中,你首先要将 surname 到了 spacestrcat(space, surname),其行为未定义为 space 只有2个元素,一个空格和一个空终止符。复制 surname 末尾破坏数组 name,你观察到的是 name 成为 ossi. 这个行为是未定义的,它在你的架构上是这样发生的,但是未定义的行为可能会有其他的后果,包括没有可见的效果或计算机崩溃。

还要注意这些备注。

  • 你应该告诉 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;
}

1
投票

首先,这些电话

scanf("%[^\n]", &name);

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

是无效的。它们必须至少看起来像

scanf("%[^\n]", name);

scanf(" %[^\n]", surname);

阵列 space 没有足够的空间来追加存储在数组中的字符串。surname. 所以这个电话

strcpy(space_surname, strcat(space, surname));

是无效的。

看来你的意思是

strcat( strcpy( space_surname, space ), surname);
© www.soinside.com 2019 - 2024. All rights reserved.