寻找一种从C文件中读取数据的好方法

时间:2014-01-25 01:58:05

标签: c file

这是我在本网站的第一个问题,我刚刚开始编程,请耐心等待。 我在使用这段代码从文件读取字符串和整数时遇到了一些麻烦,它们用分号“;”分隔它以行数开头。该文件是这样的:

13;
A;15;B;1;0;0;0;
A;9;C;0;3;2;0;
A;9;D;0;4;0;2;
A;3;E;2;3;2;0;
A;7;F;5;5;3;1;
A;5;G;5;7;6;0;
A;13;H;0;0;0;0;
A;1;I;8;1;0;0;
A;1;J;2;2;1;0;
A;6;K;7;3;2;0;
A;5;L;2;4;3;0;
A;12;AA;0;3;2;0;
A;9;BA;0;1;0;0;

我尝试做的是创建一个接收文件指针(fp)的函数和在main函数中读取的行数。它将读取文件并将矩阵和字符串保存在矩阵中:

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

char timesjogos[100][2][100];
int golsjogos[100][3];
int faltasjogos[100][3];
int camajogos[100][3];
int cverjogos[100][3];

int ReadGames(FILE *caminho,int njogos){
    printf("starting to read jogos.\n");
    int i=0;
    while(fscanf(caminho, " %[^;];%d[^;];%[^;];%d[^;];%d[^;];%d[^;];%d[^;];",
        timesjogos[i][0], &golsjogos[i][0], timesjogos[i][1], &golsjogos[i][1],
        &faltasjogos[i][0], &camajogos[i][0], &cverjogos[i][0]) == 7)
   {
        if(i < njogos)
            i++;
        else
            break;
    }    
}

int main()
{
    FILE *fp;
    int nbets;
    fp = fopen("jogos.txt", "r");
    if (!fp){
        printf ("Error trying to open file.");
    }
    fscanf(fp, " %d[^;];", &nbets);
    ReadGames(fp, nbets);
}

我怀疑的是%[^;];我以前读过每个字符串; ,我应该使用%d [^;]为整数?这样做的正确方法是什么?

另外,我使用全局变量保存读取的信息,问题是它们可能不够大,无法保存大量的行(我的教授制作了一个24180行文件来测试我们的代码)。我正在考虑使用它在第一行中给出的行数来在函数内部制作预先大小的矩阵,但是如何在函数结束后返回或保存它?

我很抱歉这些巨大的代码,但我想展示所有细节。我非常感谢您提供更有经验的帮助:D

1 个答案:

答案 0 :(得分:1)

%[^;]表示法读取由任意数量的非分号组成的字符串。遇到分号时解析停止。对于数字,无论如何解析都以分号停止;分号不是数字表示的一部分。

您对%d[^;]的使用意味着fscanf()正在寻找一个整数(%d),然后是一个开放的方括号,插入符号,分号和近似方括号。当然,这些不会出现在输入中,因此扫描失败。

因此,您的输入循环应该是:

while (fscanf(caminho, " %[^;];%d;%[^;];%d;%d;%d;%d;",
              timesjogos[i][0], &golsjogos[i][0], timesjogos[i][1],
              &golsjogos[i][1], &faltasjogos[i][0], &camajogos[i][0],
              &cverjogos[i][0]) == 7)
{
    ...
}

您可能更愿意为%[^;]转换规范指定最大长度; %99[^;]因为timesjogos的第三维是100,所以{{1}}是合适的。指定的长度和使用的长度之间存在一个一个一个的区别(由于古代历史而被赋予;在此之前就是这样的第一个C标准,C标准编纂现有做法)。