在C中打印出一串字符串

时间:2015-04-19 20:19:53

标签: c arrays file

我试图读取一个包含10行的文件,如下所示:

000000 52.3 65.2 98.7 96.3 100.0 25.0 95.6 98.7 82.5 63.1
111111 81.0 68.6 54.2 96.3 74.2 78.6 98.5 62.1 64.7 75.0
222222 52.6 63.5 25.4 42.6 32.0 22.1 52.3 96.6 98.5 63.2
333333 98.2 65.3 65.4 93.5 32.6 37.5 63.5 91.0 96.3 82.5
444444 96.3 85.2 74.1 36.9 25.8 14.7 12.3 13.4 63.5 98.4
555555 93.6 82.5 74.1 63.1 65.2 63.5 98.7 63.2 63.8 64.0
666666 95.2 61.5 97.8 52.3 63.3 33.3 44.4 55.5 66.6 77.7
777777 11.1 22.2 33.3 44.4 55.5 66.6 77.7 88.8 99.9 100.0
888888 12.3 23.4 34.5 45.6 56.7 67.8 78.9 89.1 91.1 98.1
999999 98.7 87.6 76.5 65.4 54.3 43.2 32.1 21.0 52.9 87.1

我需要逐行读取文件到一个字符串,所以目前我有:

#include<stdio.h>

int main()
{
    FILE *p;
    char *line[10], *buffer; //Array of strings and a buffer string
    int a;
    p = fopen("assign6.dat", "r+");
    for(a = 0; a < 10; a++) {
        fscanf(p, "%[^\n]", buffer); //Read until we reach a newline
        fgetc(p); //Read the newline
        line[a] = buffer;
        printf("%s\n", line[a]);
    }
    for(a = 0; a < 10; a++) {
        printf("%s\n", line[a]);
    }
    fclose(p);
    return 0;
}

所以我声明了一个指向char的指针数组来存储所有10行数据。第一个printf语句打印出正确的数据。但是第二个for循环中的第二个printf语句反复打印出文件的最后一行(10次)。那么为什么这些printf语句在它们是同一个东西时会打印出不同的东西。

3 个答案:

答案 0 :(得分:3)

复制字符串

您需要更改此内容:

line[a] = buffer;

到此:

strcpy(line[a], buffer);

它会起作用。原因是line[a]buffer是指针,通过使它们相等,你最终会指向内存中的相同地址。

What is strcpy?

Whis is this the case?

分配内存

您需要为字符串分配内存,但尚未这样做。

从你的档案判断,改变这个:

char *line[10], *buffer;

到这个

char line[10][129], buffer[129];

是一种快速解决方案。我正在分配129个字符,因为文件的字符串最大长度为6,我们需要为null character多一个空格。你可以随意改变它。否则,您可能希望动态分配内存。

How to dynamically allocate memory using malloc

答案 1 :(得分:1)

因为buffer是指向内存的指针。每次运行fscan()时,缓冲区指向的字符串都会被写入,而行[a]都具有缓冲区指针的值,因此它们都指向相同的内存位置。在该位置只存储最后一行。

您需要使用

存储每一行
strcpy(line[a], buffer); // Instead of line[a] = buffer;

答案 2 :(得分:1)

两个问题:

没有为buffer分配内存。

fscanf(p, "%[^\n]", buffer);

没有为line[a]

分配内存
line[a] = buffer;

使用预先分配的缓冲区来读取文件和字符串以进行进一步复制可能会很方便。

enum {MaxLineLength = 128};
char buffer[MaxLineLength];

string line[10];

请注意,对于buffer,程序在实际读取之前无法知道实际长度,因此需要长度上限。