如何从文件中读取并解析它

How to read from a file and parse it

我有一个 .txt 文件,其中包含一些格式如下的值:

0,30,25,10

现在,我打开文件并将其存储到数组中

char imposta_tratt[300]; 
FILE *fp;
fp = fopen("/home/pi/Documents/imposta_trattamento.txt", "r");
if (fp == 0) return;
fread(imposta_tratt, sizeof(imposta_tratt), 1, fp);
fclose(fp);

现在我希望用我的数据填充数组。我用 , 分隔值,所以我继续解析它:

const char delim[2] = ",";
int t=0;
char *token = strtok(imposta_tratt, delim);
    while (token!=NULL){
    
        strcpy(tratt[t],token);
        token = strtok(NULL, delim);
        tratt[t]=token;
        t++;
    }

这里,参考文件.txt中的内容,我希望有tratt[0]=0; tratt[1]=30; tratt[2]=25;等等,但似乎我遗漏了什么,因为它不是这样的。

我只想将 txt 文件的值存储在单个变量中。有人可以帮忙吗?

假设"in.txt"有内容

0,30,25,10

下面的程序使用 fscanf 将整数读入 tratt 数组 one-by-one。当我们使用 fscanf 读取整数时,我们确保它的 return 值符合预期。如果没有,我们关闭文件并退出。如果 fscanf 的 return 值不符合预期,程序还会打印出发生的错误类型。目前,如果发生任何错误,程序将停止。但是,您可以根据发生的错误使程序的行为有所不同。

作为输出,程序打印所有读入 tratt 数组的整数。输出是

0
30
25
10

现在这个程序假设我们知道要读入的元素数量tratt。如果我们不这样做,我们可以允许在数组需要更多元素时动态分配更多内存,或者 "in.txt" 可能包含一个数据结构,例如,在文件的 beginning/end 处记录有关文件的信息,例如文件中的数字数量和数据类型(二进制文件最适合这种情况)。这些只是几种可能性。

更好的方法可能是读取 one-by-one 中的字符(例如,使用 getc)并使用 strtol 将字符数字序列转换为 long int (我会采取与此类似的方法)。

不过,这种方法更简洁并且应该足够了。

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

#define FILE_NAME "in.txt"
#define MAX_LEN 4

int main(void) {

    int i, tratt[MAX_LEN];
    FILE *fp = fopen(FILE_NAME, "r");      /* open file for reading */

    /* if cannot open file */
    if (fp == NULL) {

        printf("Cannot open %s\n", FILE_NAME);
        exit(EXIT_FAILURE);

    }

    /* read integer, checking return value of scanf as expected */
    if (fscanf(fp, "%d", &tratt[0]) != 1) {
        if (ferror(fp))
            printf("fscanf: read error\n");
        else if (feof(fp))
            printf("fscanf: end of file\n");
        else
            printf("fscanf: matching failure\n");

        fclose(fp);
        exit(EXIT_FAILURE);
    }

    for (i = 1; i < MAX_LEN; i++)
        /* read comma plus integer, checking return value of scanf */
        if (fscanf(fp, ",%d", &tratt[i]) != 1) {
            if (ferror(fp))
                printf("fscanf: read error\n");
            else if (feof(fp))
                printf("fscanf: end of file\n");
            else
                printf("fscanf: matching failure\n");

            fclose(fp);
            exit(EXIT_FAILURE);

        }
    fclose(fp);    /* close file */

    /* print integers stored in tratt */
    for (i = 0; i < MAX_LEN; i++)
        printf("%d\n", tratt[i]);

    return 0;

}

您想要实现的目标可以简单地使用 fgets():

来完成
bool read_file_content(const char *filename, const size_t tsizemax, int tratt[tsizemax], size_t *tsize, const char *delim)
{
    // Attempt to open filename.
    FILE *fp = fopen(filename, "r");
    if (!fp) return false; // Return false upon failure.
    
    // Try to read one line. If you have more, you need a while loop.
    char imposta_tratt[300];
    if (!fgets(imposta_tratt, sizeof imposta_tratt, fp)) {
        fclose(fp);
        return false;
    }
    
    *tsize = 0;
    char tmp[300]; // Temporary buffer. Used for conversion into int.
    char *token = strtok(imposta_tratt, delim);
    
    while (token && *tsize < tsizemax) {
        strncpy(tmp, token, sizeof tmp);
        tratt[(*tsize)++] = atoi(tmp);
        
        token = strtok(NULL, delim);
    }
    
    fclose(fp);
    return true;
}
  • const char *filename: 您要解析的文件。
  • const size_t tsizemaxtratt 数组的最大大小。控制大小很重要,否则你的代码会出现缓冲区溢出(想想当你的文件有超过 100 个标记时,例如)。
  • int tratt[tsizemax]:将保存值的数组。
  • size_t *tsize:读取的token个数(与tsizemax结合使用)。
  • const char *delim:分隔符,在你的例子中是 ,.

这是你的 main():

int main(void)
{
    int tratt[100];
    size_t size = 0;
    
    if (!read_file_content("in.txt", 100, tratt, &size, ",")) {
        puts("Failed");
        return 1;
    }
    
    for (size_t i = 0; i < size; ++i)
        printf("%d\n", tratt[i]);
}

输出:

0
30
25
10