C动态数组大小

wqsoz72f  于 2023-08-03  发布在  其他
关注(0)|答案(4)|浏览(93)

你好,我是新的编码,只是想知道为什么下面的代码:

#include <stdio.h>

int main() {

for(int i = 0; 1 ; i++) {

    char x;
    char z[1+i];
    x=getchar();
    if (x == '\n'){
        *(z+i) = '\0';
        printf("%s",z);
        break;}
    *(z+i) = x;
    printf("%s, %d = %c, i = %d\n",z, (z+i),*(z+i),i);
}

return 0;
}

字符串
的C不适用于超过15个字符的输入?(我不认为这是因为我的电脑的当前状态,因为我尝试了它与在线编译器,它仍然打破了16个字符,但话又说回来,我是新的编码。谢谢。(如果答案是:“这在C中是不可能的”或类似的话,请不要离开它,并解释为什么这是不可能的)。
PS:我检查了一些类似的问题,我的,但我不知道他们在做什么,如果这篇文章是重复的,我真的很感激,如果你能把我链接到解决我的问题后,我会删除这篇文章后不久,如果是这样的话.
这是我的程序的输入和输出,有16个字符

1234567890123456
1, 6421952 = 1, i = 0
12, 6421953 = 2, i = 1
123, 6421954 = 3, i = 2
1234, 6421955 = 4, i = 3
12345, 6421956 = 5, i = 4
123456, 6421957 = 6, i = 5
1234567, 6421958 = 7, i = 6
12345678, 6421959 = 8, i = 7
123456789, 6421960 = 9, i = 8
1234567890, 6421961 = 0, i = 9
12345678901, 6421962 = 1, i = 10
123456789012, 6421963 = 2, i = 11
1234567890123, 6421964 = 3, i = 12
12345678901234, 6421965 = 4, i = 13
123456789012345, 6421966 = 5, i = 14
1234567890123456p@, 6421967 = 6, i = 15

Process returned 0 (0x0)   execution time : 4.076 s
Press any key to continue.


这是15个字符的输入和输出

123456789012345
1, 6421952 = 1, i = 0
12, 6421953 = 2, i = 1
123, 6421954 = 3, i = 2
1234, 6421955 = 4, i = 3
12345, 6421956 = 5, i = 4
123456, 6421957 = 6, i = 5
1234567, 6421958 = 7, i = 6
12345678, 6421959 = 8, i = 7
123456789, 6421960 = 9, i = 8
1234567890, 6421961 = 0, i = 9
12345678901, 6421962 = 1, i = 10
123456789012, 6421963 = 2, i = 11
1234567890123, 6421964 = 3, i = 12
12345678901234, 6421965 = 4, i = 13
123456789012345, 6421966 = 5, i = 14
123456789012345
Process returned 0 (0x0)   execution time : 4.150 s
Press any key to continue.


正如你所看到的,它在15个字符的输入下工作得很好,但是在16个字符时中断了,这就是我想要解决的问题。

rfbsl7qr

rfbsl7qr1#

你很幸运,一切都很顺利
1.您正在打印字符串,但没有确保在某处存在终端0。除了当您看到\n时,但对于所有其他情况,没有任何东西表明存在终端0
1.每个z是一个不同的数组(具有不同的大小)。你不能指望它继承你在它的前身中已经放置的任何东西。当然,你不能发誓它也不会。有一段时间,它起作用了:z的地址对于某些迭代来说显然是相同的(可能是因为一些对齐的考虑,但是您不应该以任何方式依赖于此。编译器以神秘的方式工作。您不应该对每个z的位置做出任何假设。
所以,如果你想在每次迭代时打印z,你必须确保在每次迭代时,它包含所有的字符,后跟一个终端0。
你所做的,是打印一个每第i次迭代,一个字符串z,它的第i个字符包含getch给出的。z的所有其他字符(第i-1个字符,以及i之后的任何字符,包括应该是终端0的字符)都是不确定的。并且在一段时间内,它恰好是前一次迭代中i-1第一次的剩余值,以及之后的任何初始值0(因为,好吧,没有说这个内存被初始化为0,但是,通常情况下,它恰好是事物的初始值)

11dmarpk

11dmarpk2#

当调用printf

printf("%s, %d = %c, i = %d\n",z, (z+i),*(z+i),i);

字符串
在for循环的每次迭代中发生,即使尚未检测到新的行字符'\n',则数组不包含字符串,除了由break语句中断的for循环的最后一次迭代。转换规范%s需要一个指向字符串的指针。
同样,要输出指针,必须使用转换说明符p
您可以通过以下方式更改printf的调用

printf("%.*s, %p = %c, i = %d\n", i + 1, z, ( void * )(z+i),*(z+i),i);


此调用输出当前迭代中存储在数组中的i + 1个字符。
尽管在任何情况下,程序都有未定义的行为,因为在for循环的每次迭代中定义的可变长度数组是否保留了前一次迭代中存储的数据是未指定的。

vi4fp9gy

vi4fp9gy3#

我知道我没有解释代码的目的,但这里是代码的最终版本,它高度基于FuzzFoo的答案。

#include <stdio.h>
#include <stdlib.h>

int str_input(char **y);

int main()
{
    char * y = NULL;

    str_input(&y);

    printf("%s\n", y);

    str_input(&y);

    printf("%s", y);

    free(y);

    return (0);
}

int str_input(char **y)
{
    int i;
    char x;

    for (i = 0; 1 ; i++)
    {
        x = getchar();
        *y = (char *)realloc(*y, (2 + i) * sizeof(char));

        if (*y == NULL)

            break;

        if (x == '\n')
        {
            (*y)[i] = '\0';
            break;
        }

        (*y)[i] = x;
        (*y)[i + 1] = '\0';
    }

    return (0);
}

字符串
希望这个版本的代码没有试图利用任何未定义的行为,并且适用于(几乎)所有长度的输入。它的目的是让str_input函数把字符串赋值给一个指针变量。(我知道它比这复杂一点,但它就是这样。)(而且内存是动态分配的,所以它实际上适用于更长的输入。)

olmpazwi

olmpazwi4#

考虑到上述情况,试试这个。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;  
    char x;
    char *z = NULL;

    for (i = 0; 1; i++)
    {
        x = getchar();
        z = (char *) realloc(z, (2 + i) * sizeof(char));
        if (z == NULL)
            break;
        z[i+1] = '\0';
        if (x == '\n')
        {
            z[i] = '\0';
            printf("%s", z);
            break;
        }
        z[i] = x;
        printf("%s, %p = %c, i = %d\n", z, (z+i), z[i] , i);
    }

    free(z);

    return (0);
}

字符串

相关问题