将fgets的缓冲区存储在数组中

3

我是从Java转来的,对C语言还不熟悉,想要写一个简短的程序,能够从stdin读取字符数组并将每个字符串存储在一个数组中。在读取完字符串后,我只想打印它们,但这时候情况就变得非常困难了。

以下是我的代码:

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


int main(){

char **stringarray[2];
char buffer[5];
int i = 0;
while( i < 2 && fgets(buffer, 5, stdin) != NULL){
    char *tmp = buffer;
    stringarray[i] = &tmp;
    i++;
}

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

}

return 0;
}

实际上,第一部分是可以编译的(即输出之前的部分)。我理解我的stringArray必须是char指针数组,因为在C中char数组基本上就是指向第一个字符的指针。起初,我只写了

while( i < 2 && fgets(buffer, 5, stdin) != NULL){
    stringarray[i] = buffer;
    i++;
}

这也可以编译,但显然我只有一个指针指向缓冲区,它只会保存最后读取的字符串。 我该怎么做才能存储一个简单的字符串数组?


1
你不需要一个指向指针的指针数组来实现这个。一个指针数组就足够了。 - Fred Foo
在你的 printf("%s\n", &stringarray[i]) 中,你使用了 地址(&-运算符)来获取第 i 个元素。这肯定不是你想要的。 - lethal-guitar
好的,我再次更改了它,但我仍然有一个问题,就是我不知道如何在循环的一次迭代期间永久存储缓冲区指向的内容。 - Curtis
地址运算符是无意中添加的。对于额外的混淆,我们感到抱歉。 - Curtis
3个回答

2
我建议按照以下方式更改您的代码。
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* to use strdup function */


int main(){

char *stringarray[2]; /* I don't understand why you use pointer to pointer than pointer, char **stringarray[2]; */
char buffer[6]; /* I suggest 6 than 5, because string has terminate byte in C */
int i = 0;
while( i < 2 && fgets(buffer, 5, stdin) != NULL){
    stringarray[i] = strndup(buffer, 5);
    i++;
}

for(int i = 0; i < 2; i++){
    printf("%s\n", stringarray[i]); /* changed stringarray */

}

return 0;
}

如果我没记错的话,strndup不是标准函数。它会复制字符串(分配内存并将原始字符串复制到其中),在Java中您不必考虑内存,但在C中,stringarray[i] = buffer 只是一个地址赋值,这意味着循环结束时 stringarray 的所有元素都将指向同一个缓冲区。 - Dabo

2

char **stringarray[2]; 就像 char ***stringarray 一样,因为数组就像是指向数组第一个值的指针。

printf需要一个 char*,而 &stringarray[i] 是一个 char**

如果一个字符串是一个数组,那么字符串数组就是一个数组的数组

所以代码是:

 int main()
{
    char stringarray[2][5];//array of (array of char)
    char buffer[5];
    int i = 0;
    while( i < 2 && fgets(buffer, 5, stdin) != NULL)
    {
        strcpy(stringarray[i],buffer); //copies the buffer into the string array
        i++;
    }

    for(i = 0; i < 2; i++)
    {
        printf("%s\n", stringarray[i]);

    }
    return 0;
}

如果您不想使用buffer,您可以直接编写以下代码:
    while( i < 2 && fgets(stringarray[i], 5, stdin) != NULL)
    {
        i++;
    }

请注意,你会得到5个字符,最后一个字符将是NUL终止符\0。由于你必须按回车键才能验证,因此在\0之前的那个字符将是换行符\n。而你实际想要的只有3个字符。

绝对不要删除,但是数组不是指针。 - Dabo
我无法访问您的链接:(。我一直认为数组分配了一些变量并保留了指向第一个变量的指针。我会进行一些研究,谢谢。 - Heckel

0

您可以使用以下动态分配技术来完成它。

#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>
int main()
{
   int num;
   int len=0;
   int i;
   printf("Enter the number of elements to be entered ");
   scanf("%d",&num);

   //Allocate memory for the array of strings 
   char **var=(char **)malloc(num * sizeof(char *));

   for(i=0;i<num;i++)
   {
      printf("Enter the string   : ");
      //get strings using getline 
      getline(&var[i],&len,stdin); 

   }
    for(i=0;i<num;i++)
   {
      printf("String %d   : %s \n",i,var[i]);


   }

    free(var);

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接