Why does scanf put a string into a char array while directly inputting it does not work?
这个问题很难命名。
基本上我有一个具有自己结构的数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| typedef struct Video
{
unsigned id ;
char title [90];
char producer [60];
}Video ;
Video arrayVideo [7];
int main ()
{
scanf("%s", arrayVideo [0]. title);
printf("%s", arrayVideo [0]. title);
} |
此代码将打印出我在 scanf 过程中编写的任何内容。
这个对 int main 的小改动;
1 2 3 4 5
| int main ()
{
arrayVideo [0]. title[90] = ("Hello");
printf("%s", arrayVideo [0]. title);
} |
什么都没有。控制台只是输出执行时间和正常业务。不输出"Hello"
- 您需要使用 strcpy() 来复制数组。
-
您是否收到有关该代码的编译警告?您正在尝试将一个字符串常量(一个指针)分配给一个字符,并在该数组的末尾分配一个。
-
arrayVideo[0].title[90] 的类型是 char 并且在数组的最后一个元素旁边。
第二个给你两个警告,告诉你出了什么问题:
1 2 3 4 5 6 7
| t.c: In function ‘main’:
t.c:14:29: warning: assignment makes integer from pointer without a cast [enabled by default]
arrayVideo[0].title[90] = ("Hello");
^
t.c:14:24: warning: array subscript is above array bounds [-Warray-bounds]
arrayVideo[0].title[90] = ("Hello");
^ |
第一个警告告诉您,您正在尝试将一个指针(指向字符串 "hello")存储到 title 数组的单个 char 中,第二个警告告诉您它无论如何都超出了范围, 所以几乎可以做任何事情,尽管在这种情况下它可能只是写入 producer 数组的第一个字符。
道德:始终启用编译器可以发出的所有警告,并注意它们。
这个问题实际上源于对指针对字符串的作用的混淆。 char title[90] 是一个存储 90 个 char 的字符数组。 title 是指向该数组的第一个元素的指针,而 title[90] 是指向数组末尾之后的一个元素的指针(因为数组索引从 0 开始,title[89] 是最后一个元素)
因此,如果我们分解这一行中发生的事情:
1
| arrayVideo[0].title[90] = ("Hello"); |
左边是指针类型,它指向arrayVideo中的第一个元素,它是一个结构,然后在该结构中指向字符,该字符在title的第一个元素之后的90个元素中,请注意,这是 91 年代元素。右侧是 const char* 类型的字符串文字。目前,这段代码只是在数组末尾分配一个指针,以指向 "hello" 字符串文字的开头地址。它不会像您希望的那样将字符串的内容复制到您的数据结构中。我有点惊讶您在编译时没有收到编译器的警告,请尝试在启用所有警告的情况下进行编译。
要正确复制字符串的内容,您需要像这样使用 strcpy:
1
| strcpy(arrayVideo [0]. title,"hello") |
这里 strcpy 的目标是 title 数组的开头,源来自 const char* 字符串文字 "hello".
- 感谢您的详细解释!我似乎没有收到任何警告告诉我这让我更加困惑。你能解释一下 char* 和 char 之间的区别吗?
-
@PejmanPoh,您可能需要使用编译器启用警告,使用 gcc 这是 -Wall 标志。对于其他编译器,它将使用不同的名称,请阅读编译器的手册。 char 和 char* 之间的区别在于 char 是一个字符,而 char* 是内存中包含 char 的位置。阅读有关指针的教程或介绍,这将真正有助于您在这里进一步理解。