我为字符串定义了一个数组。如果我以第一个元素不是空字符串的方式定义它,它工作正常。当它是一个空字符串时,另一个字符串的下一个scanf()
停止读取输入字符串,程序停止执行。
现在我不明白如何定义字符串数组会影响scanf()
对输入的读取。
char *str_arr[] = {"","abc","","","b","c","","",""}; // if first element is "abc" instead of "" then works fine
int size = sizeof(str_arr)/sizeof(str_arr[0]);
int i;
printf("give string to be found %d\n",size);
char *str;
scanf("%s",str);
printf("OK\n");
答案 0 :(得分:1)
声明指针不会在内存中为它分配缓冲区并且不会对其进行初始化,因此您尝试取消引用未初始化的指针(str
),这会导致未定义的行为。
请注意,如果在读取字符串时未小心使用,scanf
将导致潜在的缓冲区溢出。我建议您阅读this page,了解如何避免它的一些想法。
答案 1 :(得分:1)
实际上,你的错误是我的兄弟。 str_arr
的初始化不会影响scanf()
的工作,但是您可能会喜欢它但实际上并非如此。如其他答案中所述,这称为未定义的行为。 C本身中的未定义行为的定义非常模糊。
C FAQ定义了“未定义的行为”,如下所示:
任何事情都可能发生;标准没有要求。该 程序可能无法编译,或者可能执行不正确(或者 崩溃或静默生成不正确的结果),或者它可能 偶然地做了程序员想要的。
它基本上意味着任何事情都可能发生。当你这样做时:
char *str;
scanf("%s",str);
它是一个UB。有时你会得到你不应该得到的结果,你认为它的工作。这就是调试器派上用场的地方。几乎每次都使用它们,特别是在开始时。其他建议w.r.t您的计划:
scanf()
使用fgets()
来读取字符串。如果你想使用scanf,那就像scanf("%ws",name);
一样使用它,其中name是字符数组,w
是字段宽度。warning that you are using str uninitialized
。继续阅读THIS ARTICLE,它有足够的信息来消除您的疑虑。
答案 2 :(得分:0)
您正在向scanf
传递未初始化为任何特定内容的指针,因此scanf
将尝试将用户提供的字符写入某个随机内存位置;这是否会导致崩溃或其他原因主要取决于运气(以及编译器如何决定设置堆栈,我们也可能将其视为“运气”)。从技术上讲,这被称为“未定义的行为” - 即就C标准而言,任何事情都可能发生。
要解决您的问题,您必须将scanf
一个足够大的缓冲区传递给您计划接收的字符串:
char str[101];
scanf("%100s",str); /* the "100" bit tells to scanf to avoid reading more than 100 chars, which would result in a buffer overflow */
printf("OK\n");
请记住,C中的char *
不相当于其他语言中的string
- char *
只是指向char
的指针,对分配一无所知。