指向字符数组的字符指针而不是赋值

标签 c arrays pointers

我正在准备一个读取文件的程序:

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

#define MAXLEN 256

int main(int argc, char** argv) {

    FILE *fp;    
    char currLine[MAXLEN];

    char **fileLines = malloc(MAXLEN * sizeof(char *));
    for (int i = 0; i < MAXLEN; i++) {
        fileLines[i] = malloc(MAXLEN * sizeof(char));
    }

    int lineCounter = 0;

    fp = fopen("sample.txt", "r");

    while (fgets(currLine, sizeof(currLine), fp)) {
    fileLines[lineCounter] = currLine;
        printf("%s", fileLines[lineCounter]);
        lineCounter++;
    }

    printf("\n\n");

    for (int i = 0; i < lineCounter; i++) {
        printf("%s\n", fileLines[i]);
    }

    /*for (int i = 0; i < MAXLEN; i++) {
        free(fileLines[i]);
    }*/
    free(fileLines);

    fclose(fp);
    return 0;
}

在 while 循环中,我从文本文件 sample.txt 中读取了一行文件:

first line
2nd
linea tres
#4

并尝试将字符数组分配给双指针中的字符指针之一,然后打印。在那一刻,打印正确,但一旦在循环之外,我再次打印每个项目,它们都打印最后一个元素:

输出:

first line
2nd
linea tres
#4

#4
#4
#4
#4

据此,我怀疑“赋值”实际上是指向局部变量 currline,它的最后一个值为 #4。那么我怎样才能正确分配读取的行而不是指向字符数组呢?感谢您提供的建议帮助

最佳答案

在读取文件的循环中,必须去掉结尾的换行符并将读取的每一行的内容复制到数组中。您当前为读取的每一行存储一个指向行缓冲区的指针。字符串数组中的所有行都指向同一个缓冲区,该缓冲区最多保存从文件中读取的最后一行。

这是这个循环的改进版本:

while (lineCounter < MAXLEN && fgets(currLine, sizeof(currLine), fp)) {
    currLine[strcspn(currLine, "\n")] = '\0';
    strcpy(fileLines[lineCounter], currLine);
    printf("%s\n", fileLines[lineCounter]);  // debug
    lineCounter++;
}

这个错误也解释了为什么你不能释放 fileLines 数组中的行。这些指针不再指向分配的空间,在传递给 free() 时调用未定义的行为。

请注意,您可以通过这种方式为从文件中读取的每一行分配确切的空间,而不是预先分配完整的行数组:

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

#define MAXLEN 256

int main(int argc, char** argv) {

    char currLine[MAXLEN];
    char **fileLines = malloc(MAXLEN * sizeof(char *));
    for (int i = 0; i < MAXLEN; i++) {
        fileLines[i] = NULL;
    }

    int lineCounter = 0;

    FILE *fp = fopen("sample.txt", "r");
    if (fp == NULL)
        return 1;

    while (lineCounter < MAXLEN && fgets(currLine, sizeof(currLine), fp)) {
        currLine[strcspn(currLine, "\n")] = '\0';
        fileLines[lineCounter] = strdup(currLine);
        lineCounter++;
    }
    fclose(fp);

    for (int i = 0; i < lineCounter; i++) {
        printf("%s\n", fileLines[i]);
    }

    for (int i = 0; i < lineCounter; i++) {
        free(fileLines[i]);
    }
    free(fileLines);

    return 0;
}

关于指向字符数组的字符指针而不是赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38647772/

相关文章:

c - 如何通过 mips 中的其他进程获取正在运行的进程堆栈的回溯?

C - 使用 getline() 从文件中打印行

ios - 使用谓词从数组中获取无序数据

c - 为什么在释放指向它的指针后我仍然可以访问结构的成员?

c - 在 C 中将一个数组分配给另一个数组时出错

php - $_GLOBAL 、 $_POST 等全局变量存储在哪里?

c - memcpy 取虚拟地址还是物理地址?

java - QuickSort 在线程 "main"java.lang.StackOverflowError 中给出异常

c - 在数组之间添加元素而不影响索引遍历

c - 如何找到数组的大小(从指向数组第一个元素的指针)?