从 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;
}
(我用过stdin
和stdout
,因为我比较懒,不想搞fly的开合。)
使用 fgets
和 fputs
比多次调用 getc
和 putc
更快,您所需要的只是一个缓冲区(在这种情况下是一个小缓冲区)存储当前行:
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;
}
这可能是一个简单的问题,答案很简单,但是通过网站搜索我没有找到任何东西(可能是因为我是 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;
}
(我用过stdin
和stdout
,因为我比较懒,不想搞fly的开合。)
使用 fgets
和 fputs
比多次调用 getc
和 putc
更快,您所需要的只是一个缓冲区(在这种情况下是一个小缓冲区)存储当前行:
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;
}