如何在C中返回2D char阵列(char double指针)?

发布于 2025-01-23 14:24:22 字数 927 浏览 0 评论 0原文

我正在阅读一个包含几行字符串(最大长度50个字符)的文件。为了存储这些字符串,我使用Calloc创建了一个Char Double-Pointer。我的代码的工作方式是因为它在文件中找到了一条线,它添加了一个新行(char *)和50列(char),然后存储该值。

我的理解是,我可以调用此方法,并获得该指针,并带有值回报。但是,我没有得到这些值,所以我检查了在哪里丢失了它,并且发现记忆在之后没有持续循环。我能够使用打印1 语句打印字符串,但打印2 使我无效。

请让我知道我在这里做错了什么。

char **read_file(char *file)
{
    FILE *fp = fopen(file, "r");
    char line[50] = {0};
    char **values = NULL;
    int index = 0;
    if (fp == NULL)
    {
        perror("Unable to open file!");
        exit(1);
    }

    // read both sequence
    while (fgets(line, 50, fp))
    {
        values = (char **)calloc(index + 1, sizeof(char *));
        values[index] = (char *)calloc(50, sizeof(char));
        values[index] = line;
        printf("%s",values[index]); // print 1
        index++;
    }
    fclose(fp);
    printf("%s", values[0]); // print 2
    return values;
}

I am reading a file that contains several lines of strings(max length 50 characters). To store those strings I created a char double-pointer using calloc. The way my code works is as it finds a line in the file it adds one new row (char *) and 50 columns (char) and then stores the value.

My understanding is that I can call this method and get this pointer with values in return. However, I was not getting the values so I check where I am losing it and I found that the memory is not persisting after while loop. I am able to print strings using print 1 statement but print 2 gives me null.

Please let me know what I am doing wrong here.

char **read_file(char *file)
{
    FILE *fp = fopen(file, "r");
    char line[50] = {0};
    char **values = NULL;
    int index = 0;
    if (fp == NULL)
    {
        perror("Unable to open file!");
        exit(1);
    }

    // read both sequence
    while (fgets(line, 50, fp))
    {
        values = (char **)calloc(index + 1, sizeof(char *));
        values[index] = (char *)calloc(50, sizeof(char));
        values[index] = line;
        printf("%s",values[index]); // print 1
        index++;
    }
    fclose(fp);
    printf("%s", values[0]); // print 2
    return values;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半夏半凉 2025-01-30 14:24:22
  1. line内容在每个循环迭代中覆盖(fgets())。
  2. 被覆盖(数据丢失),并在每个迭代上泄漏内存index> 1
  3. value [index]是在每个迭代上分配的内存,当您在以下行上用line的地址覆盖它时泄漏。
  4. line是一个本地变量,因此您无法将其返回到范围不超出范围的呼叫者。
  5. 呼叫者无法判断多少条条目value包含。

这是一个具有一些更改的工作实现。错误时,它关闭文件并释放分配的内存并返回null而不是退出。移动printf()到呼叫者:

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

#define BUF_LEN 50

char **read_file(char *file) {
    FILE *fp = fopen(file, "r");
    if(!fp) {
        perror("Unable to open file!");
        return NULL;
    }
    char **values = NULL;
    char line[BUF_LEN];
    unsigned index;
    for(index = 0;; index++) {
        char **values2 = realloc(values, (index + 1) * sizeof(char *));
        if(!values2) {
            perror("realloc failed");
            goto err;
        }
        values = values2;
        if(!fgets(line, BUF_LEN, fp)) break;
        values[index] = strdup(line);
    }
    fclose(fp);
    values[index] = NULL;
    return values;
err:
    fclose(fp);
    for(unsigned i = 0; i < index; i++) {
        free(values[i]);
    }
    free(values);
    return NULL;
}

int main() {
    char **values = read_file("test.txt");
    for(unsigned i = 0; values[i]; i++) {
        printf("%s", values[i]);
        free(values[i]);
    }
    free(values);
    return 0;
}

fgets()返回'\ n'或最多buf_len -1的数据。这意味着给定的value [i]可能会以\ n结束。您可能需要此行为,或者您希望value [i]是一致的,并且不包含任何输入的任何尾随\ n irrengardless。

strdup()_posix_c_source&gt; = 200809L而不是标准C,
因此,如果您使用构建-STD = C11符号将无法定义。

  1. line content is overwritten on each loop iteration (by fgets()).
  2. values is overwritten (data loss) and leaks memory on each iteration index > 1.
  3. value[index] is allocated memory on each iteration which leaks as you overwrite it with the address of line on the following line.
  4. line is a local variable so you cannot return it to caller where it will be out of scope.
  5. caller has no way to tell how many entries values contain.

Here is a working implementation with a few changes. On error it closes the file and frees up memory allocated and return NULL instead of exiting. Moved printf() to caller:

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

#define BUF_LEN 50

char **read_file(char *file) {
    FILE *fp = fopen(file, "r");
    if(!fp) {
        perror("Unable to open file!");
        return NULL;
    }
    char **values = NULL;
    char line[BUF_LEN];
    unsigned index;
    for(index = 0;; index++) {
        char **values2 = realloc(values, (index + 1) * sizeof(char *));
        if(!values2) {
            perror("realloc failed");
            goto err;
        }
        values = values2;
        if(!fgets(line, BUF_LEN, fp)) break;
        values[index] = strdup(line);
    }
    fclose(fp);
    values[index] = NULL;
    return values;
err:
    fclose(fp);
    for(unsigned i = 0; i < index; i++) {
        free(values[i]);
    }
    free(values);
    return NULL;
}

int main() {
    char **values = read_file("test.txt");
    for(unsigned i = 0; values[i]; i++) {
        printf("%s", values[i]);
        free(values[i]);
    }
    free(values);
    return 0;
}

fgets() returns line ending in '\n' or at most BUF_LEN - 1 of data. This means a given value[i] may or may not be ending with a \n. You may want this behavior, or you want value[i] to be consistent and not contain any trailing \n irregardless of the input.

strdup() is _POSIX_C_SOURCE >= 200809L and not standard c,
so if you build with --std=c11 the symbol would not be defined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文