【问题标题】:Copying a specific column of a file to another file in C将文件的特定列复制到C中的另一个文件
【发布时间】:2013-08-01 17:49:15
【问题描述】:

我有两个文件,第一个看起来像这样

125 6.678
435 9.084
234 8.874

等等,大约有 2,048,000 个条目,由我的程序生成。 第二个文件是gnuplot生成的文件,看起来有点像:

65 321456 985
78 98374  834
54 8493   848

以此类推,大约有 2,048,000 个条目。

现在我需要做的是使用 3D 中的 gnuplot 将第一个文件的第二列和第二个文件的两列相互绘制。我认为第一个任务是将它们全部放入同一个文件中,我只想编写一个简单的 c 程序来快速读取这两个文件并将相关列放入一个文件中,但我不知道该怎么做。我知道如何复制文件的全部内容并使用 c 程序将它们写入另一个文件 - 例如,我有以下代码:

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

int main (int argc, const char * argv[])
{
FILE *avalanche_size_BM;
FILE *avalanche_size_BM_2000;
char ch;


avalanche_size_BM = fopen("/Users/maheensiddiqui/Documents/MSc_Proj/avalanche_size_BM.dat","r");

if (avalanche_size_BM == NULL) 
{
    printf("I couldn't open.\n");
    exit(0);
}
avalanche_size_BM_2000 = fopen("/Users/maheensiddiqui/Desktop/avalanche_size_BM_2000.dat", "w");
if (avalanche_size_BM_2000 == NULL) 
{
    printf("I couldn't open.\n");
    exit(0);
}

printf("\n success!!");

while((ch=getc(avalanche_size_BM))!=EOF)
      putc(ch,avalanche_size_BM_2000);

fclose(avalanche_size_BM);
fclose(avalanche_size_BM_2000);



return(0);
}

但是我如何告诉它只读取第一个文件中的第二列和第二个文件中的前两列并将它们(而不是所有列)复制到第三个文件,我可以用它来绘制我的 3 -D 情节。

任何帮助将不胜感激!

谢谢

【问题讨论】:

  • 嗨 Maheen:从外观上看,您似乎正在使用 Mac OSX 创建文件。您是否需要在 C 中执行此操作,或者您不在乎使用什么,只要您可以从第一个文件生成第二列和第二个文件的第一两列的第三个文件?
  • 除非您有理由为此编写代码,否则我怀疑您最好使用像 awk 这样的工具来为您完成这项工作。至于怎么看stackoverflow.com/questions/5467690/…hcs.harvard.edu/~dholland/computers/awk.html
  • 嗨!不,我不需要使用 c,但我什至不知道存在 awk 之类的东西,我会试一试,非常感谢!

标签: c file-io gnuplot


【解决方案1】:

非 C 答案

这假设您只想要结果,并不真正担心如何在 C 中完成。

要使用简单的命令行工具生成文件,您可以使用pasteawk 来获取结果:

paste 读取多个文件并将所有行组合在一起,以制表符分隔

因此,如果您有两个文件,例如 foo.txt 和 bar.txt,它们具有以下内容:

foo.txt:

a1 b1 c1 
a2 b2 c2

bar.txt:

d1 e1 f1
d2 e2 f2

paste foo.txt bar.txt 输出:

a1 b1 c1    d1 e1 f1
a2 b2 c2    d2 e2 f2

然后您可以使用 awk 过滤掉您想要的列。

例如,如果您想要列 2、4 和 5 (b1, d1, e1),您可以使用以下内容:

paste foo.txt bar.txt | awk '{ print $2 " " $4 " " $5 }'

我将假设两个文件都有相同数量的条目 从 Finder -> Utilities

在 OSX 中启动命令 shell

在 shell 提示下,您可以这样做:

$ cd Desktop
$ paste avalanche_size_BM.dat avalanche_size_BM_2000.dat | \
    awk '{ print $2 " " $4 " " $5 }' > avalanche_size_3d.dat

这将在桌面子目录中从第一个文件的第 2 列和第二个文件的前两列创建一个名为 avalanche_size_3d.dat 的文件(因为它们在粘贴在一起时最终位于位置 4 和 5)。

C-答案

这本质上就像编写一个小型粘贴实用程序

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

int main()
{
     FILE *fp1 = fopen ("file1", "r");
     FILE *fp2 = fopen("file2", "r");
     FILE *out = fopen("fileout", "w");

     while (!feof(fp1) && !feof(fp2)) {
         char buf[256], col1[256], col2[256], col3[256];
         if ( fgets(buf, sizeof(buf), fp1) == 0 )
            break;
         sscanf(buf, "%s %s", col2, col1); /* we only need col1, col2 is reused later */
         if ( fgets(buf, sizeof(buf), fp2) == 0 ) 
            break;
         sscanf(buf, "%s %s", col2, col3); 
         fprintf(out, "%s %s %s\n", col1, col2, col3);
     }
     fclose(fp1);
     fclose(fp2);
     fclose(out);
}

【讨论】:

  • 只使用paste 很好,因为gnuplot 能够自己选择特定的列:splot "&lt; paste file1 file2" using 2:3:4。顺便说一句:目前正在开发 merge 命令,应该直接在 gnuplot 中执行此操作。
  • 这正是我想要的,非常感谢!很好解释!干杯!
  • @Christoph 说的太对了,我的大脑甚至都没有考虑过 gnuplot……此外,对于目标实用程序无法提取列数据的其他情况,awk 步骤是一个很好的例子
【解决方案2】:

在 C 语言中,最简单的方法是从两个文件中的每一个中读取一行,然后将这两行作为单行打印到第三个文件中。一旦你这样做了,你就可以解析你真正想要打印的每一行的哪些部分,但是将两个文件合并到一个文件中可能足以让你使用gnuplot 来绘制你的数据。

要读入一行输入,您可以使用fgets()。您可以为每行使用两个单独的缓冲区。从您从第一个文件获得的第一行,您删除最后的换行符,然后将其打印到新文件中。然后,打印第二个文件中的行。

char buf1[MAX_LINE];
char buf2[MAX_LINE];
FILE *infile1 = fopen(..., "r");
FILE *infile2 = fopen(..., "r");
FILE *outfile = fopen(..., "w");

while (fgets(buf1, sizeof(buf1), infile1) != 0
       && fgets(buf2, sizeof(buf2), infile2) != 0) {
    strchr(buf1, '\n')[0] = '\0';
    fprintf(outfile, "%s %s", buf1, buf2);
}

fclose(outfile);
fclose(infile1);
fclose(infile2);

读取一行输入后,您可以使用sscanf() 解析输入以检索您有兴趣打印的行部分:

int file1_column1;
double file1_column2;
sscanf(buf1, "%d %lf", &file1_column1, &file1_column2);

int file2_column1;
int file2_column2;
int file2_column3;
sscanf(buf2, "%d %d %d", &file2_column1, &file2_column2, &file2_column3);

您可以使用fprintf() 打印出这些值:

fprintf(outfile, "%f %d %d\n", file1_column2, file2_column1, file2_column3);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 2019-06-23
    • 2021-03-16
    • 1970-01-01
    相关资源
    最近更新 更多