【问题标题】:Reading data separated by ';' from file读取以';'分隔的数据从文件
【发布时间】:2018-09-07 20:53:02
【问题描述】:

我正在尝试从使用; 格式化的文件中读取数据。 数据将永远是这样的:

char[];int;int%;int

char[] 可以有任意数量的空格,读取数据时应忽略%

我正在使用fscanf()(我只能使用它)从文件中读取数据。
现在我的那部分代码是:

fscanf(file, "%[^;]%d%d%d", f_name, &f_id, &f_score, &f_section_num) != EOF)

是否有我需要的正则表达式?或者,如何更正我的fscanf

【问题讨论】:

  • 看看这是否有帮助。 stackoverflow.com/questions/19466894/…
  • while(4 == fscanf(file, "%[^;];%d;%d%%;%d", ...));这样的东西呢
  • @Anand 我在发布这个问题之前查看了它,甚至尝试了他们所做的,但我仍然收到错误。
  • 请注意,由于%[^;] 也使用换行符,您的程序将像abc\nxyz;3;4%;5 这样的两行输入读取为一行。
  • fscan 不支持正则表达式。格式字符串的语法,文档不清楚怎么办?

标签: c file parsing


【解决方案1】:

您可以使用fscanf 使用此格式字符串读取文件:

"%[^;];%d;%d%%;%d"
  • %[^;]:读到第一个;
  • ;:忽略;
  • %d:读取一个整数
  • ;:忽略;
  • %d:读取一秒整数
  • %%:忽略%
  • ;:忽略;
  • %d:读取三分之一整数

不要忘记通过测试fscanf(...) == 4 来测试fscanf 的成功转化次数

所以代码看起来像:

FILE *f = fopen(...);
char name[64];
int i, integers[3];

while (fscanf(f, "%[^;];%d;%d%%;%d", name, &integers[0], &integers[1], &integers[2]) == 4)
{
    printf("name is %s\n", name);
    for (i = 0; i < 3; ++i)
    {
        printf("i[%d] = %d\n", i, integers[i]);
    }        
}
fclose(f);

【讨论】:

    【解决方案2】:

    您也可以使用strtok()。例如,如果您对每个条目使用一个结构,如下所示,

    typedef struct {
        char name[64];
        int id, score, section_num;
    } entry_t;
    

    以下内容将读取文件的每一行,如下所示。

    char line[128] = {'\0'};
    char *field = NULL;
    entry_t entry;
    
    while (fgets(line, sizeof(line), fp)) {
        field = strtok(line, ";");
        if (!field || strlen(field) > sizeof(entry.name)) continue;
        strcpy(entry.name, field);
        field = strtok(NULL, ";");
        if (!field) continue;
        entry.id = atoi(field);
        field = strtok(NULL, ";%");
        if (!field) continue;
        entry.score = atoi(field);
        field = strtok(NULL, ";");
        if (!field) continue;
        entry.section_num = atoi(field);
        // Do whatever you need with the entry - e.g. print its contents
    }
    

    为简洁起见,我删除了一些必要的样板代码。有关完整示例,请参阅 http://codepad.org/lg6BJ0hk

    如果您需要检查整数转换的结果,您可以使用strtol() 而不是atoi()

    【讨论】:

    • 我试过用这个,但我觉得我现在做的有点没必要。
    • @Varun.R:诚然,它更啰嗦。如果您有使用 fscanf() 的解决方案,请按照我的建议进行。我想我还是会把这个答案留在这里,作为替代方案。
    【解决方案3】:

    以下代码将允许您从文件中读取以; 分隔的数据:

    char msg[100];
    int  a;
    char b[100];
    int  c;
    
    fscanf(fptr, "%[^;];%d;%[^;];%d", msg, &a, b, &c);
    printf("%s\n %d\n %d\n %d\n", msg, a, atoi(b), c);
    

    【讨论】:

    • 这可能不安全地假设该行中的任何组件都不会超过 99 个字符。
    • 我认为第三个字段是一个整数,后跟%,所以;25%; 或类似的。您似乎将其视为一个字符串,这只是部分正确 - 您必须将字符串转换为整数,可能在最后验证百分比符号之后。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多