在C语言中读取一个字符串数组

3

我想要读取一个字符串数组。数组的大小需要使用mallocalloc在运行时决定,也就是说,字符串的数量需要作为输入接受。我尝试了下面的代码,但它没有起作用。

char *array;
array=(char*)malloc(sizeof(char)*t); //t is the size of array
for(int temp=0;temp<t;temp++)
{
    gets(a[temp]);
}

相同的方法也适用于整数数组。
请帮助我找到解决方案。

顺便提一下,sizeof(char)是多余的;它已经被C标准定义并要求为1。 - glglgl
@glglgl 对,sizeof(char)是多余的。相反,我应该使用malloc(1*t)。 - Jainendra
为什么不直接使用 malloc(t) 呢? :-) - glglgl
4个回答

5

C语言没有自动内置支持存储字符串的功能,也没有“字符串”变量,可以自动增长以容纳适当数量的字符。您需要自己分配内存。

现在您正在为适当数量的字符指针分配空间,但没有为任何字符分配空间。因此,gets()调用会写入未分配的内存,这是未定义的行为。由于整数完全适合单个分配,这就是类似代码为整数工作的原因。字符串更复杂,因此您需要做更多的工作。

如果这些字符串的长度有任何已知的上限,您可以使用固定长度的临时缓冲区,然后在了解所需大小后将其从中复制到新分配的动态内存中。如果没有这样的限制,您需要重复相同的概念,通过读取固定块、存储该块,并且如果没有找到行尾,则读取另一个块,使用realloc()增加此字符串的内存分配,追加新字符,并重复直到行结束。

顺便说一下,您应该始终避免使用gets(),因为它不支持保护您的程序免受缓冲区溢出的影响。更好的方法是使用在同一页上记录的fgets()。


1

你所分配的空间只能存储一个以零结尾格式存储的字符串。

如果你想要存储多个字符串的数组,你需要使用malloc()来分配一个char *类型的数组,再加上多个字符串。

此外,gets()是不安全的,因为它没有大小限制。相反,使用fgets()。它有以下签名:

char *fgets(char *restrict s, int n, FILE *restrict stream);

由于它需要一个流,所以你只需要提供 stdin

因此,读取一行的最佳方式是

char * read_one_line(uint32_t maxbufsize)
{
    char * s = malloc(maxbufsize);
    if (!fgets(s, maxbufsize, stdin)) {
        free(s);
        return NULL;
    } else {
        char * s2 = realloc(s, strlen(s)+1); // +1 for the NUL at the end
        if (s2) {
            return s2;
        } else {
            return s; // should never happen as the memory block is shrinked
        }
    }
}

此函数分配所需的一行内存,读取后适当地调整大小,并将其留给调用者在适当的时间释放。


读取输入中字符串数组的另一种高效方法是什么? - Jainendra

1
您需要首先为字符串数组(char*)分配空间:
char **array;
array = (char**)malloc(sizeof(char*)*t);

然后您需要为它们分配空间(假设这些字符串的最大字符数为50):

int i = 0, m = 50;
for (i = 0; i < t; ++i)
    array[i] = (char*)malloc(sizeof(char)*51); // 51 = 50 characters + '\0'

然后你就可以做你想做的事情了:

for(i = 0; i < t; ++i)
    scanf("%50s", array[i]);

不要使用gets,最好使用指定宽度scanf%50s = 50个字符+ '\0')。


0

只要记住在字符数组中最后应该有一个NUL字符。

因此,使用allocmalloc分配t+1字节的内存。

t字节用于表示字符,1个字节用于终止NUL字符。

for循环之后,即循环外部,只需编写如下内容:

a[temp] = '\0';

然后你就可以在工作中使用它。

我希望它能够正常工作。

它会看起来像这样。

char *a = malloc(sizeof((char)*(t+1)));//t is number if characters
int temp;
for(temp=0; temp<t; temp++) {
    gets(a[temp]);
}
a[temp] = 0;

然后打印数组,你会得到一个字符串。
printf("%s",a);

你想为每个字符都调用 malloc 吗?! - glglgl
为(t+1)次仅分配一次malloc - Chander Shakher Ghorela - Guru
在你的上下文中,“times”是什么意思?你是指字节吗? - glglgl
1
是的,我指的是(t+1)个字节...,其中't'个字节用于存储字符串,1个字节用于存储NULL。 - Chander Shakher Ghorela - Guru
  1. 你的代码示例只读取一个字符串(一行)。
  2. 它使用本质上不安全的 gets()。不好。
- glglgl

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