字符指针指向字符数组而不是分配

时间:2016-07-28 22:29:30

标签: c arrays pointers

我准备了一个程序来读取文件:

sample.txt

在while循环中,我从文本文件first line 2nd linea tres #4 中读取了一行文件:

first line
2nd
linea tres
#4

#4
#4
#4
#4

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

输出:

currline

由此,我怀疑是什么"任务"实际上是在指向局部变量#4,其最后一个值为data want(drop=l1 l2 cnt tmp); set have; by id; retain cnt max_measure_3m l1 l2; if first.id then do; max_measure_3m = 0; cnt = 0; l1 = .; l2 = .; end; cnt = cnt + 1; tmp = lag(measure); if cnt > 1 then l1 = tmp; tmp = lag2(measure); if cnt > 2 then l2 = tmp; if measure > l1 and measure > l2 then max_measure_3m = measure; run; 。那么我怎样才能正确分配行读取而不是指向字符数组?感谢您提供任何建议方面的帮助

2 个答案:

答案 0 :(得分:1)

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

以下是此循环的改进版本:

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;
}

答案 1 :(得分:0)

您正在将fileLines[lineCounter]中的每个指针设置为指向CurrentLine的相同字符串,因此在执行结束时,它们都应打印存储在CurrentLine中的最后一个字符串。

要解决此问题,您需要将CurrentLine内容(在每次迭代中)复制到为fileLines[lineCounter]&amp;分配的内存中。已经为malloc指定了指针,例如,您可以使用:
strncpy(fileLines[lineCounter], CurrentLine, strlen(CurrentLine))