C 存储用户输入而不声明任意大的数组。

C 存储用户输入而不声明任意大的数组。,c,C,我接受字符输入并存储它,而不声明任意大的数组。问题是代码没有打印存储的值(尽管它完美地打印了我输入的元素数)。工作原理是:在第一个for循环执行中,创建“b”并将“c”复制到其中(c现在包含任意内容),然后用户覆盖“b”中的内容,然后将更新的“b”复制到“c”。在第二个循环和后面的循环中,“c”基本上是旧的“b”,而“b”通过复制“c”并在最后输入新元素而不断更新 #include<stdio.h> #include<stdlib.h> #include<strin

我接受字符输入并存储它,而不声明任意大的数组。问题是代码没有打印存储的值(尽管它完美地打印了我输入的元素数)。工作原理是:在第一个for循环执行中,创建“b”并将“c”复制到其中(c现在包含任意内容),然后用户覆盖“b”中的内容,然后将更新的“b”复制到“c”。在第二个循环和后面的循环中,“c”基本上是旧的“b”,而“b”通过复制“c”并在最后输入新元素而不断更新

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char e = 'a';   
    char *b,*c = &e;    
    printf("start entering the characters and enter Z to terminate:\n");
    char d;
    int i,m;    
    for(i=0;(d=getchar()) != 'Z';i++)
    {
        b=malloc(sizeof(char)*(i+1));
    strcpy(b,c);        
    scanf("%c",b+i);
    c=malloc(sizeof(char)*(i+1));
    strcpy(c,b);
    }
    printf("-----------------------------------------------------------------\n");
    int q=strlen(b);    
    printf("%d\n",q);
    //printf("%s\n",b);
    for(m=0;m<q;m++)
        printf("%c",b[m]);
    return 0;   
}
#包括
#包括
#包括
int main()
{
字符e='a';
字符*b,*c=&e;
printf(“开始输入字符并输入Z以终止:\n”);
chard;
int i,m;
对于(i=0;(d=getchar())!='Z';i++)
{
b=malloc(sizeof(char)*(i+1));
strcpy(b,c);
scanf(“%c”,b+i);
c=malloc(sizeof(char)*(i+1));
strcpy(c,b);
}
printf(“----------------------------------------------------------------\n”);
int q=斯特伦(b);
printf(“%d\n”,q);
//printf(“%s\n”,b);

对于(m=0;m我不确定问题代码为什么同时使用“getchar()”和“scanf()”;也许我遗漏了什么

而且,正如“BLUEPIXY”所提到的,realloc()更好

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

    int main()
        {
        char   *b    = NULL;  /* This will be the reference to the self-growing array. */
        size_t  bLen = 0;     /* This is the length of the string in 'b' (not counting the string termination character.) */

        for(;;)
          {
          char *x; /* Used to safely grow the array 'b' larger. */
          int d;   /* Use an 'int'.  'getchar()' returns an 'int', (not a 'char'). */

          /* Get a character from stdin. */
          d=getchar();
          if('Z' == d)
             break;

           /* Safely grow the array 'b' large enough to hold the one more character. */
          x=realloc(b, (bLen+1) * sizeof(*b));
          if(NULL == x)
             {
             fprintf(stderr, "realloc() failed.\n");
             exit(1);
             }
          b=x;

          /* Store the character in the array and re-terminate the string. */
          b[bLen++] = d;
          b[bLen] = '\0';
          }

        printf("-----------------------------------------------------------------\n");
        printf("%s\n",b);

       if(b)
          free(b);

        return 0;
        }
#包括
#包括
#包括
int main()
{
char*b=NULL;/*这将是对自增长数组的引用*/
size\u t bLen=0;/*这是“b”中字符串的长度(不计算字符串终止字符)*/
对于(;;)
{
char*x;/*用于安全地将数组“b”扩大*/
int d;/*使用“int”。“getchar()”返回一个“int”(而不是“char”)*/
/*从stdin获取一个字符*/
d=getchar();
如果('Z'==d)
打破
/*安全地将数组“b”扩大到足以容纳一个或多个字符*/
x=realloc(b,(bLen+1)*sizeof(*b));
if(NULL==x)
{
fprintf(stderr,“realloc()失败。\n”);
出口(1);
}
b=x;
/*将字符存储在数组中并重新终止字符串*/
b[bLen++]=d;
b[bLen]='\0';
}
printf(“----------------------------------------------------------------\n”);
printf(“%s\n”,b);
如果(b)
免费(b);
返回0;
}
一些印象:

  • 为所有变量指定一个字符的名称会使阅读此代码的人很难理解您要做什么

  • 使用
    malloc()
    分配的内存块用完后,需要使用
    free()
    释放它

  • >代码> STRCYPY()/>代码是用于null结尾的字符串,所以我不认为它会做你所期望的。请考虑<代码> MycPy*()/<代码>。你使用的<代码> STRULL()/代码>也有同样的问题。你不需要用任何东西来替换它,因为<代码> i <代码>应该已经给你字符计数。

  • 您的
    scanf()
    语句是否试图将字符复制到缓冲区中?只需使用简单的赋值,如b[i]=d
  • 如果
    Z
    是用户的第一个按键,
    b
    将永远不会被初始化,当您尝试在循环后的代码中访问它时,会发生不好的事情

  • 循环中每一次迭代中重新分配内存是非常低效的。相反,考虑在一开始就分配少量的空间,比如说,20个字符的值。然后在循环的主体中,如果你的缓冲区有足够的空间来容纳一个新的字符,那么你需要做的就是复制一个字符。如果你的缓冲区缺少空间,然后重新分配一个更大的内存块,但不仅仅是一个额外的字符;为另外20个字符(或其他任何字符)保留空间

  • 每次重新分配应该只需要一次调用
    malloc()
    (或者,更好的是,按照BLUEPIXY的建议,
    realloc()
    )。我不确定为什么要使用两个

  • Null在结尾终止输入,以便在需要显示时将其视为字符串


  • 如果您对此有任何具体问题,我很乐意提供帮助。

    (1)不考虑以“\0”结尾的C字符串。(2)输入在两个位置使用。(3)使用
    realloc
    更好。我知道为时已晚,也许我太懒了!!但我确实从@mahonrimoriancumer提供的回复和代码中学到了很多,并采用了两种方式,即“在循环的每次迭代中重新分配内存”和“在开始时分配少量空间,然后增加空间”。我想问一件事,@mahonri提供的代码中,这真的有必要吗?或者为什么要创建char*x,然后将b=x相等。相反,如果我们这样做,会有什么问题:b=realloc(b,(bLen+1)*sizeof(*b));我认为这也应该有效。@user3647970,这在专业C编程中实际上非常重要。如果realloc()失败时,它返回“NULL”;但不会释放“b”指向的原始内存。因此,在“b”中捕获realloc()的返回值,如果realloc()失败,程序将不再引用“b”指向的原始内存;因此,无法正确释放()该原始内存(即:“内存泄漏”).对于问题中提到的学术项目来说,没有什么真正的问题;但是对于一个长期不断泄漏内存的项目来说,这将是非常糟糕的。我知道这已经太晚了,也许我太懒了!!但是我真的从回复和你的代码中学到了很多,并且通过以下两种方式进行了部署:“在循环的每次迭代中重新分配内存”和“分配少量空间”