从C中的文本文件中提取列表的列

时间:2016-02-18 11:12:36

标签: c parsing file-management

这可能是一个简单的问题,答案很简单,但搜索网站我没有找到任何东西(也许是因为我是C编程的新手),除了python代码,我已经写过了,效率很低。

假设我在timestamps.txt文件中有一个数据列表,格式如下:

<large integer>, <integer between 1 and 8>
<large integer>, <integer between 1 and 8>

依此类推(文件大约4GB)......

我想要做的只是将第二列复制到另一个文件,比如singles.txt

到目前为止我所做的工作,但这是一种相当天真的方法,需要花费太多时间。这是我的代码:

int main(int argc, char const *argv[])
{
    FILE *input_file;
    FILE *output_file;
    char ch;
    int check = 0;

    input_file = fopen("timestamps.txt","r");
    output_file = fopen("singles.dat","w");
    if (!input_file)
        return -1;

    while((ch = getc(input_file))!=EOF)
        {

            if(check==1)
                {putc(ch,output_file);putc('\n',output_file);}

            if(ch == ',')
                check = 2;
            else
                check -= 1;

        }


    fclose(input_file);
    fclose(output_file);

    return 0;
}

我确信有更快的方法,但我似乎无法做任何事情。 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

您的想法并不是那么糟糕,但您应该将变量check设置为0或1,具体取决于您是否要复制当前输入数据。并且您必须使用每个新行重置检查。

或者,您可以计算您当前所在的字段,并在字段是您想要的字段时复制数据。

这是一个将want逐字分隔的列sep复制到输出文件的版本:

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

int main(int argc, char const *argv[])
{
    FILE *in = stdin;
    FILE *out = stdout;

    int want = 1;
    int col = 0;
    int sep = ',';

    for (;;) {
        int c = getc(in);

        if (c == EOF) break;

        if (c == sep) {
            col++;
        } else if (c == '\n') {
            col = 0;
            putc(c, out);
        } else if (col == want) {
            putc(c, out);
        }
    }

    return 0;
}

(我已经使用了stdinstdout,因为我很懒,并且不想做开启和关闭的内容。)

答案 1 :(得分:0)

使用fgetsfputs比对getcputc的多次调用要快,您只需要一个缓冲区(在这种情况下是一个缓冲区)来存储当前行:

int main(int argc, char const *argv[])
{
    FILE *input_file;
    FILE *output_file;
    char buf[128];
    char *ptr;

    input_file = fopen("timestamps.txt","r");
    output_file = fopen("singles.dat","w");
    if (!input_file)
        return -1; /* use EXIT_FAILURE instead of -1 */
    /* you forget to check output_file */
    while (fgets(buf, sizeof buf, input_file)) {
       ptr = strchr(buf, ','); /* find the comma */
       if (ptr != NULL) {
           fputs(ptr + 1, output_file); /* +1 to skip the comma */
       }
    }
    fclose(input_file);
    fclose(output_file);
    return 0;
}