创建未知字符串数组-未定义行为

问题描述

以下代码是什么错误或不确定的行为?

如果事先不知道字符串的数量和大小,我suggested this可以创建一个字符串数组,在简短讨论之后,建议我打开一个新问题。

当我使用gcc编译时,以下代码产生了预期的结果,但是尽管行为未定义(毕竟是未定义的),但这仍然可能发生。

那么,怎么了?

int n,i;

printf("How many strings? ");
scanf("%d",&n);

char *words[n];

for (i = 0; i < n; ++i) {
    printf("Input %d. string: ",i + 1);
    scanf("%s",&words[i]);
}

for (i = 0; i < n; ++i) {
    printf("%s\n",&words[i]);
}

编辑:

我现在因为错过了这个而感到愚蠢,我想找回正确的答案只是让我错过了我的错误。但是,其他人可能会从我的错误中学到东西: 我猜想&运算符的操作是完全错误的。我以为它可以给我单词所指向的位置,但是当然却恰恰相反。查看答案。

解决方法

doSomething()scanf("%s",&words[i]);调用*未定义的行为,因为传递了错误类型的数据。
printf("%s\n",&words[i]);scanf()中,printf()都要求%s指向有效缓冲区,但是传递的是char*

也不要忘记在读取之前分配缓冲区来存储字符串。

尝试一下:

char**
,
def factorial2(n):
    if n == 1:
        f = 1
    else:
        a = yield from factorial2(n - 1)
        f = n * a
    # Yielded by the generator
    yield f
    # Returned to `yield from`
    return f

for a in factorial2(12):
    print(a)
# 1
# 2
# 6
# 24
# 120
# 720
# 5040
# 40320
# 362880
# 3628800
# 39916800
# 479001600

创建未初始化的指针数组

char *words[n];

将值写入foo指向的位置

未指定单词的指针所指向的位置,因此它们可以指向可能导致段错误的任何地方

接下来的单词是一个字符**

words [i]是一个字符*

&words [i]是一个字符**

%s期望使用char *,所以再次发生未定义的行为

所以您首先必须使用例如malloc来初始化word数组,然后将值写入word [i]

,

此:

char *word;

是一个指针,在用作诸如字符串的容器之前,它需要指向足以容纳该字符串的内存。

例如,这将起作用

word = malloc(80*sizeof(*word));
if(word)
{//success,continue

类似于上面的,

char *word[n];   

扩展名是n个指针的数组。在将任何指针用作某些字符串的容器之前,每个指针都必须指向自己的内存位置。假设已经扫描了值n,这将起作用:

for(int i=0;i<n;i++)
{
    word[i] = malloc(80*sizeof(*word[i]));//80 for illustration
    if(!word[i])
    {//handle error...

一旦分配了内存,就可以填充字符串。
但是,为确保用户输入不会溢出word的每个实例定义的缓冲区,请在格式字符串中使用宽度说明符:

更改:

scanf("%s",&words[i]);

收件人:

scanf("%79s",words[i]);//note & is not needed as the symbol for a char array serves as the address
//      ^^    ^