C语言 如何实现动态字符串矩阵


int i=0, ii=1, j, k, choose=0;
char q='a';
char **words = (char **)malloc(sizeof(char));
words[i] = (char *)malloc(sizeof(char)+1);
do {
    printf("you want again(0, 1)n");
    scanf("%d", &choose);
    j = 0; k = 1;
    do {
        fflush(stdin);
        q = getchar();
        *words[j] = q;
        words[j] = (char *)realloc(words[j], (k+1) * sizeof(char));
        j++; k++;
    } while (q != 'n');
    *words[k] = '';
    i++; ii++;
    words = (char**)realloc(words ,ii*sizeof(char));
} while (choose);
puts("pRINT");
int d = 0, t = 0;
for (d = 0; d < i; d++) {
    printf("%sn", words[d]);
}

我需要创建一个单词矩阵,但我不知道每个单词的大小以及会有多少个。这就是为什么我在开始时和每次迭代后使用 malloc realloc (size+1) ,但在第一次迭代之后,我收到内存错误。我做错了什么,问题出在哪里?

虽然您可以自由地使用面向字符的输入读取和一次索引字符,但有更简单的方法可以解决此问题。例如,使用面向行的输入函数(如fgetsgetline),您可以一次读取/存储用户输入的整行数据。

getline的优点是分配足够的内存来保存用户输入的每个字符串(由您来实施任何长度的健全性检查)。但是,如果您使用 getline ,则只需在达到初始指针数时关注重新分配。此外,如评论中所述,没有理由为每个输入realloc(您可以,它只是效率很低)。您可以分配一些合理数量的指针,然后仅在达到该限制时才realloc

下面是一个显示替代方案的简短示例。查看一下,如果您有任何问题,请告诉我。 (注意:与其在手动生成的EOF上停止循环,不如简单地检查是否nchr = 1,如果用户只需按 Enter 而不输入数据,则自动退出。这取决于你。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NPTR 32
int main (void) {
    char *line = NULL;
    char **words = NULL;
    size_t i, n, idx = 0, nptr = NPTR;
    ssize_t nchr = 0;
    /* initially allocate NPTR pointers */
    if (!(words = malloc (sizeof *words * NPTR))) {
        fprintf (stderr, "error: virtual memory exhausted.n");
        return 1;
    }
    printf ("nEnter data [ctrl+d] ([crtl+z] on windows) to quitnn");
    while (printf (" input ") && (nchr = getline (&line, &n, stdin)) != -1) 
    {   /* for each line read */
        while (nchr && (line[nchr-1] == 'n' || line[nchr-1] == 'r'))
            line[--nchr] = 0;  /* strip newline or carriage rtn    */
        words[idx++] = strdup (line);
        if (idx == nptr) {  /* if limit reached -- realloc */
            void *tmp = realloc (words, 2 * nptr * sizeof *words);
            if (!tmp) {
                fprintf (stderr, "error: realloc - memory exhausted.n");
                exit (EXIT_FAILURE);
            }
            words = tmp;
            nptr *= 2;
        }
    }
    free (line);
    printf ("nnInput provided by user:nn");
    for (i = 0; i < idx; i++)   /* print strings */
        printf (" words[%2zu] : %sn", i, words[i]);
    putchar ('n');
    for (i = 0; i < idx; i++)   /* free memory */
        free (words[i]);
    free (words);
    return 0;
}

使用情况/输出

$ ./bin/getline_input
Enter data [ctrl+d] ([crtl+z] on windows) to quit
 input my
 input dog
 input has
 input fleas
 input
Input provided by user:
 words[ 0] : my
 words[ 1] : dog
 words[ 2] : has
 words[ 3] : fleas

当用户在空白行上按 [Enter] 时退出

如上所述,使用输入后退出循环的另一种简单方法是检查getline的返回值是否大于 1 。例如,您可以将初始提示和条件替换为:

printf ("nEnter data, ([Enter] on blank line to quit)nn");
while (printf (" input ") && (nchr = getline (&line, &n, stdin)) > 1)
{ ...

我发现有时更方便。

主要错误之一是:

char **words = (char **)malloc(sizeof(char));

words = (char**)realloc(words ,ii*sizeof(char));

您需要将其更改为

char **words = (char **)malloc(sizeof(char *));

words = (char**)realloc(words ,ii*sizeof(char *));

这是因为单词指向字符 *。

第二个问题是:

j = 0; k = 1;
do {
    fflush(stdin);
    q = getchar();
    *words[j] = q;
    words[j] = (char *)realloc(words[j], (k+1) * sizeof(char));
    j++; k++;
} while (q != 'n');
*words[k] = '';

您需要改为执行以下操作:

j = 0;k = 1;
do {
    fflush(stdin);
    q = getchar();
    words[i][j] = q;
    j++; k++;
    words[i] = (char *)realloc(words[i], (k+1) * sizeof(char));
} while (q != 'n');
words[i][j] = '';

相关内容

  • 没有找到相关文章

最新更新