为什么scanf将字符串放入char数组,而直接输入它却不起作用?
很难给这个问题命名 基本上我有一个数组,它有自己的结构为什么scanf将字符串放入char数组,而直接输入它却不起作用?,c,scanf,C,Scanf,很难给这个问题命名 基本上我有一个数组,它有自己的结构 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
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的这一小改动
int main()
{
arrayVideo[0].title[90] = ("Hello");
printf("%s", arrayVideo[0].title);
}
什么也没找到。控制台只输出执行时间和正常业务。不输出“Hello”这个问题实际上源于对指针在字符串中的作用的混淆
chartitle[90]
是存储90char
s的字符数组title
是指向该数组第一个元素的指针,title[90]
是指向数组末尾后一个元素的指针(因为数组索引从0开始,title[89]
是最后一个元素)
所以如果我们把这一行的情况分解一下:
arrayVideo[0].title[90] = ("Hello");
左侧是指针类型,它指向arrayVideo
中的第一个元素,这是一个结构,然后在该结构中指向超过title
第一个元素90个元素的字符,请注意,这是91s元素。右侧是const char*
类型的字符串文字。目前,这段代码只是在数组末尾指定一个指针,指向“hello”
字符串文本开头的地址。它不会像您希望的那样将字符串的内容复制到数据结构中。我有点惊讶,编译此文件时没有收到编译器的警告,请尝试在启用所有警告的情况下编译
要真正正确复制字符串的内容,您需要像这样使用:
在这里,strcpy的目标是
标题数组的开始,源是常量char*
字符串文本“hello”
这个问题实际上源于对指针在字符串中的作用的混淆chartitle[90]
是存储90char
s的字符数组title
是指向该数组第一个元素的指针,title[90]
是指向数组末尾后一个元素的指针(因为数组索引从0开始,title[89]
是最后一个元素)
所以如果我们把这一行的情况分解一下:
arrayVideo[0].title[90] = ("Hello");
左侧是指针类型,它指向arrayVideo
中的第一个元素,这是一个结构,然后在该结构中指向超过title
第一个元素90个元素的字符,请注意,这是91s元素。右侧是const char*
类型的字符串文字。目前,这段代码只是在数组末尾指定一个指针,指向“hello”
字符串文本开头的地址。它不会像您希望的那样将字符串的内容复制到数据结构中。我有点惊讶,编译此文件时没有收到编译器的警告,请尝试在启用所有警告的情况下编译
要真正正确复制字符串的内容,您需要像这样使用:
这里,strcpy的目标是title
数组的开始,源是const char*
字符串literal“hello”
第二个给你两个警告,告诉你出了什么问题:
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
数组的单个字符中,第二个警告告诉您它无论如何都超出了范围,因此可能会执行任何操作,虽然在本例中,它可能只是写入producer
数组的第一个字符
寓意:始终启用编译器的所有警告,并注意它们。第二个警告提供两个警告,告诉您出现了什么问题:
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
数组的单个字符中,第二个警告告诉您它无论如何都超出了范围,因此可能会执行任何操作,虽然在本例中,它可能只是写入producer
数组的第一个字符
寓意:始终启用编译器可以使用的所有警告,并注意它们。您需要使用strcpy()来复制数组。您在该代码上收到编译警告吗?您正在尝试将字符串常量(指针)分配给一个字符,并在该数组的结尾处分配一个。类型为arrayVideo[0]。title[90]
是char
,位于数组的最后一个元素旁边。您需要使用strcpy()复制数组。是否收到有关该代码的编译警告?您正在尝试将字符串常量(指针)指定给一个字符,并在该字符的数组末尾指定一个。类型为arrayVideo[0]。标题[90]
为char
,位于数组的最后一个元素旁边。感谢您的详细解释!我似乎没有收到任何关于这件事的警告,这让我更加困惑。您能解释一下char*和char之间的区别吗?@PejmanPoh,您可能需要在编译器中启用警告,在gcc中这是-Wall
标志。对于其他编译器,它将是一个不同的名称,请阅读编译器手册。char
和char*
之间的区别在于char
是一个字符,char*
是内存中包含char
的位置。阅读有关指针的教程或介绍,这将真正帮助您进一步理解这里。感谢您的详细解释!我似乎没有收到任何关于这件事的警告,这让我更加困惑。您能解释一下char*和char之间的区别吗?@PejmanPoh,您可能需要使用编译器启用警告,使用gcc thi