程序以错误的方式打印字符串。字符串
Program Prints the string in the wrong way. strcpy
输入姓名和姓氏后(例如:姓名: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);
}
strcat(dest, src)
会将 src
连接到 dest
上。您的缓冲区 space
(长度 1 不包括空终止符)不足以容纳两者。此外,您的 space_surname
将溢出,因为您将大小为 1 的字符串 (space
) 和 大小为 40 的字符串 (surname
) 存储到大小为 40 的缓冲区。至少增加到 41 大小。也不需要 space
字符串,因为 space
是字符,可以直接设置。
space_surname[0] = ' ';
space_surname[1] = '[=10=]'; // So you know where to concat to
strcat(space_surname, surname);
请注意,您 运行 与 name
有同样的问题。您正在尝试将 name
(长度 40)、space
(长度 1)和 surname
(长度 40)全部存储到 name
中。您需要创建一个大小为 81 或更大的新 full_name
变量并将其存储到其中。
在您的代码中,您首先将 space
末尾的 surname
与 strcat(space, surname)
连接起来,这具有未定义的行为,因为 space
只有 2 个元素,一个 space 和空终止符。在末尾复制 surname
会破坏数组 name
,当 name
变为 ossi
时,您会看到它。这种行为是未定义的,它在您的体系结构上以这种方式发生,但未定义的行为可能会产生其他后果,包括没有可见的效果或计算机崩溃。
另请注意以下备注:
- 您应该告诉
scanf()
要存储到 name
和 surname
中的最大字符数,以避免在超长输入时出现未定义的行为。
- 你应该传递
name
而不是 &name
。
- 您应该测试
scanf()
的 return 值以避免无效输入的未定义行为,例如在文件意外结束或第一个空行的情况下 scanf()
.
- 您可以定义具有使行为始终定义的大小的数组。
为了更简洁的方法,您将使用 2 个不同的数组 firstname
和 surname
作为用户输入,并将名称构建到第三个数组 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;
}
对于初学者来说,这些电话
scanf("%[^\n]", &name);
scanf(" %[^\n]", &surname);
无效。他们必须至少看起来像
scanf("%[^\n]", name);
scanf(" %[^\n]", surname);
数组 space
没有足够的 space 来追加存储在数组 surname
中的字符串。所以这个调用
strcpy(space_surname, strcat(space, surname));
无效。
你的意思好像是
strcat( strcpy( space_surname, space ), surname);
输入姓名和姓氏后(例如:姓名: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);
}
strcat(dest, src)
会将 src
连接到 dest
上。您的缓冲区 space
(长度 1 不包括空终止符)不足以容纳两者。此外,您的 space_surname
将溢出,因为您将大小为 1 的字符串 (space
) 和 大小为 40 的字符串 (surname
) 存储到大小为 40 的缓冲区。至少增加到 41 大小。也不需要 space
字符串,因为 space
是字符,可以直接设置。
space_surname[0] = ' ';
space_surname[1] = '[=10=]'; // So you know where to concat to
strcat(space_surname, surname);
请注意,您 运行 与 name
有同样的问题。您正在尝试将 name
(长度 40)、space
(长度 1)和 surname
(长度 40)全部存储到 name
中。您需要创建一个大小为 81 或更大的新 full_name
变量并将其存储到其中。
在您的代码中,您首先将 space
末尾的 surname
与 strcat(space, surname)
连接起来,这具有未定义的行为,因为 space
只有 2 个元素,一个 space 和空终止符。在末尾复制 surname
会破坏数组 name
,当 name
变为 ossi
时,您会看到它。这种行为是未定义的,它在您的体系结构上以这种方式发生,但未定义的行为可能会产生其他后果,包括没有可见的效果或计算机崩溃。
另请注意以下备注:
- 您应该告诉
scanf()
要存储到name
和surname
中的最大字符数,以避免在超长输入时出现未定义的行为。 - 你应该传递
name
而不是&name
。 - 您应该测试
scanf()
的 return 值以避免无效输入的未定义行为,例如在文件意外结束或第一个空行的情况下scanf()
. - 您可以定义具有使行为始终定义的大小的数组。
为了更简洁的方法,您将使用 2 个不同的数组 firstname
和 surname
作为用户输入,并将名称构建到第三个数组 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;
}
对于初学者来说,这些电话
scanf("%[^\n]", &name);
scanf(" %[^\n]", &surname);
无效。他们必须至少看起来像
scanf("%[^\n]", name);
scanf(" %[^\n]", surname);
数组 space
没有足够的 space 来追加存储在数组 surname
中的字符串。所以这个调用
strcpy(space_surname, strcat(space, surname));
无效。
你的意思好像是
strcat( strcpy( space_surname, space ), surname);