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

Extract a column of a list from a text file in C

这可能是一个简单的问题,答案很简单,但是通过网站搜索我没有找到任何东西(可能是因为我是 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;
}

我确定有更快的方法,但我似乎无法使任何工作正常进行。 任何帮助将不胜感激。

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

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

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

#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,因为我比较懒,不想搞fly的开合。)

使用 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;
}