char* username[30];
memset(username,0x00,30);
scanf("%s",&username);
这会使指针指向内存中的随机位置还是可以安全使用?
char *username[30]
是一个指针数组,而不是字符。所以你的代码是非常错误的(因为不安全)。要获取您需要的字符数组:
char username[30];
char* username[30]; //is array of char pointers.
//Allocate memory for these pointers using calloc(). so no need of memset().
memset(username,0x00,30);//can be removed.
scanf("%s",&username);//It should be scanf("%s",username[i]);
@perreal,添加了示例。
#define SIZE 100 //100 chars...
char* username[30];
int i;
for(i = 0; i < 30; i++)
{
username[i] = calloc(SIZE, sizeof(char)); //Add Fail checks if needed.
scanf("%s",username[i]);
}
所以使用上面的代码,你可以得到 30 个字符串。如果您只需要一个 30 字符的字符串,那么
char username[30];
memset(username,0x00,30);
scanf("%s",username);
足够的。
和
memset(username,0x00,30);
您正在初始化指针数组的前 30 个字节,而不是整个数组
memset(username,0, sizeof(username));
将所有内容设置为 0 尽管简单的循环对读者来说更清晰(恕我直言)
for (int i = 0; i < 30; username[i++] = NULL) {;}
不要这样做:
scanf("%s",&username);
scanf 不会神奇地分配任何东西——“用户名”是一个指针数组并且是 NULL 指针,scanf 应该如何知道如何分配内存等?而是做一个循环,让用户输入一个字符串,为该字符串分配内存(+1),将字符串复制到分配的内存并将其分配给“用户名 [i]”。
您可能想要的是:
int i;
char* username[30];
for(i = 0; i < 30; i++)
{
username[i] = calloc(100, sizeof(char)); // or whatever size your string is.
scanf("%s",username[i]);
}
... Code using usernames ...
for(i = 0; i < 30; i++)
{
free(username[i]);
}
但就个人而言,我可能会选择:
int i;
char username[30][100];
for(i = 0; i < 30; i++)
{
scanf("%s",username[i]);
}
节省了以后必须释放指针。
这会将 30 个字符串读入您的用户名数组。
如果您只想读取一个用户名:
char username[30] = {0}; // Same as memset, but shorter to write!
scanf("%s", username);
尽管正如其他人所建议的那样, scanf() 不是读取“用户生成的输入”的最佳功能 - 它适用于您的程序已经“检查”的数据(也就是说,它不包含“有趣的东西”,适合提供的长度等)并写入文件[使用 fscanf()]。对于用户输入,用于fgets()
读取一行文本,然后以适合从字符串中获取实际数据的任何方式处理它。
例如,如果某个用户名的字符数超过 100 个 [或在上一个示例中为 30 个],则字符串将溢出,并且不会产生任何好处 [在非常糟糕的情况下,您直到很久以后才会注意到,这使调试变得困难-如果幸运的话,它会立即崩溃]。
char* username[30];
memset(username,0x00,30);
scanf("%s",&username);
上面你的代码会崩溃,因为你试图输入没有分配内存的指针。所以首先你为指针分配内存,然后你读入那个内存位置。
char *username[30]
这是一个指向字符的指针数组。
去做char username[30]