我遇到一个问题,当我使用scanf将字符串存储到char指针时,我有3个输入 - 名字,姓氏和年龄,姓氏的最后一个字符值被年龄替换为年龄输出更好地解释。
Q-riosity v0.0.1
输入你的名字
叶夫根尼·
输入你的姓氏 丹尼连科
输入您的年龄
22
Evgeny Danilenk22,你今年22岁
这是代码
void getUserDetails(char** value)
{
char *key[3] = {"name", "surname", "age"};
int keySize = sizeof(key)/sizeof(char*);
printf("Q-riosity v0.0.1\n");
int i = 0;
for(i = 0; i<keySize; i++)
{
printf("Enter your %s \n", key[i]); // name, surname, age
scanf("%s", &value[i]); //stores value at index i
}
printf("%s, %s, you are %s years old\n", &value[0], &value[1], &value[2]);
}
修改
输入您的姓名
叶夫根尼·
输入你的姓氏
丹尼连科
输入您的年龄
22
分段故障
int main(int argc, char* argv[])
{
char *key[3] = {"name", "surname", "age"};
int keySize = sizeof(key)/sizeof(char*);
printf("Q-riosity v0.0.1\n");
char* value[keySize];
int i = 0;
for(i = 0; i<keySize; i++)
{
printf("Enter your %s \n", key[i]);
scanf("%s", value[i]);
}
for(i = 0; i<keySize; i++)
{
printf("%s : %s \n", key[i], value[i]);
}
return 0;
}
答案 0 :(得分:2)
您正在将char**
传递给printf
和scanf
。 %s
期望char*
,而不是char**
。所以,替换以下内容:
scanf("%s", &value[i]);
printf("%s, %s, you are %s years old\n", &value[0], &value[1], &value[2]);
与
scanf("%s", value[i]);
printf("%s, %s, you are %s years old\n", value[0], value[1], value[2]);
新代码有一个问题:
char* value[keySize];
创建一个大小为keySize
的{{1}}指针数组。这些指针未初始化,可以指向任何地方。您通过char
写入这些未初始化的指针,这将调用着名的未定义行为。
解决方案包括:
scanf
内存。使用2D数组:
malloc
答案 1 :(得分:2)
嗯,输出Danilenk22
表明你的value
变量在调用者中声明为大小为8的连续char数组。
当您阅读Danilenko
作为姓氏时,您会写入10个字符(包括终止\0
。前8个填充保留数组,最后2个填入数组年龄。当您稍后阅读年龄,它会覆盖这两个字符。
让我们看一下内存(?表示单元化或不关心字符):
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
E v g e n y \0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
E v g e n y \0 ? D a n i l e n k o \0 ? ? ? ? ? ?
E v g e n y \0 ? D a n i l e n k 2 2 \0 ? ? ? ? ?
但是八位字符也可能是64位架构上指针的大小......
您的编辑显示您无法正确初始化value
指针数组。假设你想要名字和姓氏有32个字符,年龄有4个字符,你可以这样做:
char _v0[32], _v1[32], _v2[4];
char* value[keySize] = { _v0, _v1, _v2 };
这样程序就不再有错误。
答案 2 :(得分:1)
替换行
printf("%s, %s, you are %s years old\n", &value[0], &value[1], &value[2]);
与
printf("%s, %s, you are %s years old\n", value[0], value[1], value[2]);
请记住,您想要打印一个值,而不是它的地址。
注意: scanf()
需要指针才能正确读取,因此其语法为
scanf("%s", &str);
答案 3 :(得分:1)
假设value
在通过之前已经完成了malloced:
只需将printf()
语句更改为
printf("%s, %s, you are %s years old\n", value[0], value[1], value[2]);
和您的scanf()
语句
scanf("%s", value[i]);
实际上,printf("%s", &str)
会调用未定义的行为,尽管它通常可以正常工作。这是因为str
和&str
具有不同的类型,尽管它们的值相同。要验证这一点,只需运行
printf("%p\n%p\n%p\n%p", (void *)str, (void *)(str + 1), (void *)&str, (void *)(&str + 1));