C语言 如何存储输入字符串从用户和存储在一个指针数组?



在我的代码中,我试图从用户获取字符串作为输入,并将它们存储在指针数组中。但是,我的代码只在指针数组的所有元素中存储最后输入的字符串。我需要做什么修改?

我的代码是:

#include <stdio.h>
#include <string.h>
void main()
{
char *names[ 4 ], name[ 10 ];
for ( int i = 0; i < 4; i++ ) {

printf( "Enter your name: " );
scanf( "%s", name );
names[ i ] = name;
}
for ( int i = 0; i < 4; i++ )
printf( "n* %s", names[ i ] );
}

输出为:

输入你的名字:Anna输入你的名字:米其林输入你的名字:史蒂文输入您的名字:Jacob

雅各
  • 雅各
  • 雅各
  • 雅各

浅Vs深拷贝:

给定两个指针p和q,语句:
p = q;

不会将q指向的内存的内容复制到p指向的内存的内容。它复制指针值,这样pq现在都指向相同的内存,并且当使用q时,通过p对内存的任何更改都会反映出来。这被称为浅拷贝。

声明

char *names[ 4 ];

声明了一个包含4个指向char指针的数组。注意,这只是为指针分配内存。


然后,在循环中:

for ( int i = 0; i < 4; i++ ) {

printf( "Enter your name: " );
scanf( "%s", name );
names[ i ] = name;
}

将缓冲区name的地址分配给数组中的每个指针。

问题:最后一次迭代后name的内容是什么?

答:雅各。

在内存中,它看起来像这样:
names[0] ----
|
names[1] ----
|----> address of ```name```
names[2] ----
|
names[3] ----          

解引用并打印这些指针的内容,然后每次打印Jacob

可能的修复:

  • 按照注释的建议使用二维数组

  • 使用malloc为字符串分配内存,并将其地址分配给指针。然后,您可以使用strcpy或POSIX的strdup将缓冲区name的内容复制到每个指针指向的内存区域(这被称为深度复制)。

注意:strdup使用malloc为字符串分配内存,所以不要忘记free它。

strdup()函数返回一个指向新字符串的指针字符串s的副本。新字符串的内存为通过malloc(3)获得,可以通过free(3)释放。(Linux的手册页)


main()定义错误

从C11:

程序启动时调用的函数命名为main。的实现没有为这个函数声明原型。应该是用int返回类型定义不带参数:

int main (void) 
{ /* ... */ }

或带两个形参(这里称为Argc和argv,尽管可以使用任何名称,因为它们是本地的函数中声明它们):

int main (int argc, char *argv[]) 
{ /* ... */ } 

或同等学历;或者以其他实现定义的方式。


缓冲区溢出漏洞:

scanf("%s", name);

等价于:

gets(name);

它将愉快地继续读取输入并溢出缓冲区。

可以考虑使用fgets:

fgets (name, sizeof (name), stdin);

fgets最多读取n - 1个字符,并以null结束字符串。

或者使用scanf:

的宽度说明符
scanf("%9s", name);