ファイルの統合プログラム

このQ&Aのポイント
  • ファイルの内容を統合し、特定の条件に一致する行だけを抜き出すプログラムを作成したいです。
  • ここでは3つのファイルを統合し、aaa.txtの一列目の文字列とbbb.txt,ccc.txtの一列目の文字列が一致する行だけを抜き出します。
  • これまではcolumnの変数を一つ一つ定義して書いていたが、今回はcolumnの数が多いため、columnの数がわからなくてもファイルを読み込めば処理を行えるプログラムを作りたいです。
回答を見る
  • ベストアンサー

ファイルの統合プログラム

----aaa.txt-------- name number band J0223 1.0 2.2 J0222 null 1.2 J0221 2.0 null J0224 2.0 2.0 ----bbb.txt--------- name time J0222 11.0 J0223 22.0 ----ccc.txt---------- name number J0222 20 J0221 J0223 10 ---望む結果------ name number band name time name number J0223 1.0 2.2 J0223 22.0 J0223 10 J0222 null 1.2 J0222 20 J0221 2.0 null J0221 J0224 2.0 2.0 上記のような中身の3つのファイル(各columnはタブで区切れられている)を用意して、aaa.txtの一列目の文字列とbbb.txt,ccc.txtの一列目の文字列が一致する行だけを抜き出してaaa.txtの各行のあとにくっつけるプログラムを書きたい(望む結果)のですが、どう書いていいわかりません.これまでは、下記のプログラムのようにいちいちcolumnの変数を定義して上記のような処理をしてきたのですが、今回扱うファイルはcolumnの数が多く(100個)、columnの変数を一つ一つ定義して書くのは非常大変になると思います.ですので、出来ればcolumnの数がわからなくともファイルを読みこませれば上記のような処理を行なってくれるプログラムが書きたいです.どなたかご教授いただけないでしょうか.回答よろしくおねがいします. 内容がわかりづらかったらすいません. ----------プログラム--------------- #include<stdio.h> int main(void) { FILE *fp ,*gp; int ret; char xl[30],nx1[30],xls[30],nx2[30],xlb[30],nb2[30]; fp=fopen("bbb.txt","r"); gp=fopen("aaa.txt","r"); while(fscanf (fp,"%s%s",xls,nx2)==2){ while(fscanf (gp,"%s%s%s%s",nx1,xl,xlb,nb2)==4){ ret=strcmp(xls,nx1); if(ret == 0){ printf("%s\t%s\t%s\t%s\t%s\t%s\n",xl,nx2,nx1,xl,xlb,nb2); } } rewind(gp); } fclose(fp); return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.2

aaa.txtの1列目しか比較項目として使わないのであれば、2列目以降はまとめて読み込めばいいでしょう。 fscanfとfgetsを併用すれば可能です。 書かれているプログラムをfscanfとfgetsを使ったプログラムに修正すると次のようになります。 while(fscanf(fp,"%s%s",xls,nx2)==2){ while(fscanf(gp,"%s",nx1)==1){ fgets(xl,256,gp); ret=strcmp(xls,nx1); if(ret == 0){ printf("%s\t%s\t%s%s\n",xls,nx2,nx1,xl); } } rewind(gp); } なお、xlのサイズは十分に大きく取っておいてください。 ファイルがaaa.txt,bbb.txt,ccc.txtの3つに増えた場合は、 まず、aaa.txt,bbb.txtの2つのファイルで上記の処理をして結果を一時ファイルに出力し、 さらに、その一時ファイルとccc.txtとの処理で結果を出力すればいいでしょう。 ただ、#1さんも書いていますが、メモリ上に読み込めるほどのデータ量なら、全件読み込んでから処理したほうが簡単だし処理時間も早くなります。

seturi38
質問者

お礼

なるほどやってみます. ありがとうございました.

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

まず確認ですが、 ・その処理ができるようにするのが目的で、C言語は手段ですか? ・C言語をマスターするのが目的で、その処理は手段ですか? 「columnの変数を一つ一つ定義して書く」などというのは面倒なので、多次元配列を用意するのが常套手段でしょう。 char data[100][30] data[0] : 0番目のカラムの文字列 data[1] : 1番目のカラムの文字列 といった具合。 また、数がわからなければ、最初行でカラム数を求めて、その後、malloc/callocなどで動的にメモリを確保する、という方法があります。 また、同じファイルを繰り返し読んでますが、メモリに余裕があれば、メモリ上の読み込んでしまうという方法もあります。 上記と合せて、char data[行][列][文字] のような3次元配列に入れることもできます。 C言語の勉強が目的なら、このようなメモリ関連の処理は非常に重要なものです。 これを避けてマスターするなどできません。 しっかりと学習してください。 ファイル処理が目的なら、C言語の文字列操作は面倒です。 他の文字列を得意とする言語、例えば、Awk, Perl ,Ruby,Python等でやることをお勧めします。 Visual BasicやExcelのVBAとかでも、Cよりははるかに楽です。

seturi38
質問者

お礼

早速の回答有り難うございます. 私は、質問に書いたような処理がしたいと考え,ちょうどc言語を勉強し始めたのでこの機会にcで書いてみようと思いました. >また、数がわからなければ、最初行でカラム数を求めて、その後、malloc/callocなどで動的にメモリを確保する、という方法があります。 「最初行でカラム数・・・」というのはどのようにすれば実現できるのでしょうか?

関連するQ&A

  • ファイル操作のプログラムについて

    下記のsample1.txtの1列目とsample2.txtの1列目の文字列が一致する行をつなげて出力するプログラムを組みたいと思い、test.cを書きましたが、うまく動きませんでした。これは何が原因なのでしょうか。 回答よろしくお願いします。 -------------------sample1.txt-------------------- J02220-2222 3.999 null J03424-2222 900.0 0.43 J03666-2223 30.0 0.23 J04000-4422 98.0 0.43 -------------------sample2.txt-------------------- J03424-2222 900.0 0.43 J03342-4423 4.000 0.99 J02220-2222 3.999 null -------------------test.c--------------------------- #include<stdio.h> int main(void) { FILE *fp ,*gp; int ret; char xl[30],nx1[30],xb[30]; char xls[30],nx2[30],xlb[30]; fp=fopen("sample1.txt","r"); gp=fopen("sample2.txt","r"); while(fscanf (fp,"%s%s%s",xl,nx1,xb)==3){  while(fscanf (gp,"%s%s%s",xls,nx2,xlb)==3){  ret=strcmp(xl,xls);  if(ret == 0){  printf("%s\t%s\t%s\t%s\t%s\t%s\n",xl,nx1,xb,xls,nx2,xlb);    }  }  } fclose(fp); return 0; } インデントが反映されいなかったらすいません。 ------------出力結果------------------- J02220-2222 3.999 null J02220-2222 3.999 null -----------望む出力結果-------------- J02220-2222 3.999 null J02220-2222 3.999 null J03424-2222 900.0 0.43 J03424-2222 900.0 0.43

  • 照合に関するプログラムについて

    2つのファイルを用意して1つが以下のaaa.txtのような数値が記述されているファイルで、もう1つがbbb.txtのようなファイルでこの中の2列目には、aaa.txtに記されている数値が含まれています。 -------aaa.txt------- -------bbb.txt------- 1.4 XMS 2.5 2.5 XMS 2.7 2.7 XMS 1.1 2.1 XMS 1.0               XMS 2.1 XMS 1.4 aaa.txtとbbb.txtそれぞれのテキストないで数字のダブリはない。bbb.txtはaaa.txtの数字をすべて含む。 aaa.txtに記述されている数値を利用して、bbb.txtの2列目で同じ数値を示すものをその数値がある行ごと取り出し、行末にnameという文字を出力し、bbb.txtの数値がaaa.txtのどの数値とも異なればそのままその行を出力するようなプログラムを書きたいと考えました。そこで、下記のようなプログラムを書いて実行したところ、こちらの意図した出力(ccc.txt)が得られませんでした。なぜ、cccのような出力にならなかったのかがわからなくて非常に困っています。どなたかこのプログラムの誤り又はもっと良い書き方を教えていただけないでしょうか。回答よろしくおねがいします。 ------------ccc.txt---------------- XMS 2.5 name XMS 2.7 name XMS 1.1 XMS 1.0 XMS 2.1 name XMS 1.4 name -----プログラム-------- #include<stdio.h> #include<string.h> int main(int argc ,char *argv[]) { FILE *fp[argc],*gp; char x[30]; int linemax,ret; double distance; int i=0; char command[30] = "wc "; char *re="> Nline.txt"; char file1[25],file2[25],file3[25],*ends;  strcat(command,argv[2]);  strcat(command,re);   system(command);  gp=fopen("Nline.txt","r"); fscanf(gp,"%d%s%s%s",&linemax,file1,file2,file3);   system("rm Nline.txt");  fp[0]=fopen(argv[1],"r");  linemax=linemax-1; while(fscanf (fp[0],"%s %lf",x,&distance==9){ while(fscanf(gp,"%lf",&dis)==1){  if(dis==distance){   printf("%s %lf name \n",x,distance);   i=0;   }else if(dis!=distance && i==linemax){    printf("%s %lf \n",x,distance);   i=0;   }   i++; }rewind(gp); } fclose(gp); fclose(fp[0]); return 0; }

  • C言語 教えてください

    data.txtの中に入っているデータを読み込み、 全て出力するというプログラムを作ろうとしています。 しかし、上手く読み込み表示させることが出来ません。 自分で出来るだけ調べたのですが、 どこがおかしいのかわからないので教えてください。 ↓↓↓現在作っているプログラムです↓↓↓ #include <stdio.h> void main(void) { FILE *fp; char number, name; if ((fp = fopen("data.txt", "r")) == NULL) { printf("FILE OPEN ERROR\n"); } else { while (fscanf(fp, "%s%s", number, name) == 2) { printf("%s-%s\n", number, name); } } fclose(fp); printf("FILE CLOSE !!\n"); } ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↓↓data.txt↓↓ 001 aaa 002 bbb 003 ccc 004 ddd 005 eee ↑↑↑↑↑↑↑↑ よろしくお願いします。

  • fpus:ファイル操作

    Cを勉強している初心者です。 このソースはコンパイルは通るのですが、 エラーがでてしまいます。 いろいろと調べてみたりもしたのですが わかりませんでした。 なぜなのでしょうか? #include <stdio.h> #include <string.h> struct student{ char name[20]; }; int main(void) { struct student s[1]; int i; int j = 1; FILE *fp; strcpy(s[0].name,"taro"); strcpy(s[1].name,"jiro"); if((fp = fopen("test.txt","w+")) == NULL) { printf("ファイルを開けませんでした\n"); return (-1); } for(i=0;i<=j;i++) { fputs(s[i].name,fp); } fclose(fp); return (0); }

  • fputs:ファイル操作

    Cを勉強している初心者です。 このソースはコンパイルは通るのですが、 エラーがでてしまいます。 いろいろと調べてみたりもしたのですが わかりませんでした。 なぜなのでしょうか? #include <stdio.h> #include <string.h> struct student{ char name[20]; }; int main(void) { struct student s[1]; int i; int j = 1; FILE *fp; strcpy(s[0].name,"taro"); strcpy(s[1].name,"jiro"); if((fp = fopen("test.txt","w+")) == NULL) { printf("ファイルを開けませんでした\n"); return (-1); } for(i=0;i<=j;i++) { fputs(s[i].name,fp); } fclose(fp); return (0); }

  • C言語のプログラムをエクセルに書き込む方法

    C言語のプログラムをエクセルに書き込みたいのですが、自分が理解していないのか、上手にできません。 前、質問(No.421727)して、教えてもらったのですがソートプログラムの実行結果もおかしい感じです。 #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000 void filewrite(int j,int i,int a[]); void main(void){ int min,s,t,i,j,k,a[N]; srand((unsigned int)time(NULL)); for(i=0;i<N;i++) a[i]=rand()%1000+1; for(j=0;j<i-1;j++){ min=a[j]; s=j; for(k=j+1;k<i;k++){ if(a[k]<min){ min=a[k]; s=k; } } t=a[j];a[j]=a[s];a[s]=t; if(j%100 == 99){ for(s=0;s<i;s++) printf("%d\t",a[s]); } filewrite(j,i,a); } } void filewrite(int j,int i,int a[]) { int s; FILE *fp; char name[15]; printf("\nfilename="); scanf("%s",name); if((fp=fopen(name,"w"))==NULL){ printf("\nCan't open the sourse file\n"); exit(1); } if(j%100 == 99){ for(s=0;s<i;s++) fprintf(fp,"%d\n",a[s]); fclose(fp); } } よろしくお願いします。

  • 構造体のファイル書き込み&読み出しに関して2

    C言語を勉強しているものです。指定した番号に構造体を書き込み、指定した番号をの構造体を出力するプログラムを作成したいのですが、表示結果画像のようになってしまいます。 デバックしても、どこが違うのかがわかりません。説明不足かとは思いますがご教授お願いします。 ↓↓ソースコード↓↓ #include<stdio.h> #include<stdlib.h> struct S_data{ char Name[10+1];/*名前*/ int Sex;/*性別*/ int Height;/*身長*/ float Weight;/*体重*/ }; void FR_data(FILE *Fp,int pos); void FW_data(FILE *Fp,int pos); void OUP_data(struct S_data tag); void INP_data(struct S_data *tag); int RF_data(FILE *Fp,struct S_data *tag,int pos); int WF_data(FILE *Fp,struct S_data *tag,int pos); void main(){ FILE *Fp; int pos=0; int Ret; Fp=fopen("aaa.dat","r+b"); if(Fp==NULL){ Fp=fopen("aaa.dat","w+b"); if(Fp==NULL){ printf("File not open\n"); exit(2); } } while(1){ printf("入力の番号[0:終了]->"); scanf("%d",&pos); if(pos==0) break; FW_data(Fp,pos); } while(1){ printf("出力の番号[0:終了]->"); scanf("%d",&pos); if(pos==0) break; FR_data(Fp,pos); } Ret=fclose(Fp); } void FR_data(FILE *Fp,int pos){ struct S_data Temp; /*出力情報*/ int Ret; /*返却値*/ memset(&Temp,'\0',sizeof(Temp)); Ret=RF_data(Fp,&Temp,pos); /*情報の読み込み*/ if (Ret!=1){ printf("File not read\n"); }else{ OUP_data(Temp); /*情報の表示*/ } } void FW_data(FILE *Fp,int pos){ struct S_data wk; /*入力情報*/ int Ret; /*返却値*/ memset(&wk,'\0',sizeof(wk)); INP_data(&wk); /*情報の入力*/ Ret=WF_data(Fp,&wk,pos); /*情報の書き込み*/ if (Ret!=1){ printf("File not write\n"); } } void OUP_data(struct S_data tag){ printf("Name:%s\n",tag.Name); if (tag.Sex==0){ printf("Sex:M\n"); }else{ printf("Sex:F\n"); } printf("Height:%d\n",tag.Height); printf("Weight:%.2f\n",tag.Weight); } void INP_data(struct S_data *tag){ memset(tag,'\0',sizeof(tag)); printf("Name-->"); scanf("%s",&tag->Name); printf("Sex[0:M1:F]-->"); scanf("%d",&tag->Sex); printf("Height-->"); scanf("%d",&tag->Height); printf("Weight-->"); scanf("%f",&tag->Weight); } int RF_data(FILE *Fp,struct S_data *tag,int pos){ int Ret_I; /*fseek返却値*/ size_t Ret_S; /*fread返却値*/ Ret_I=fseek(Fp,sizeof(tag)*(pos),SEEK_SET); Ret_S=fread(tag,sizeof(tag),1,Fp); return Ret_S; } int WF_data(FILE *Fp,struct S_data *tag,int pos){ int Ret_I; /*fseek返却値*/ size_t Ret_S; /*fwrite返却値*/ Ret_I=fseek(Fp,sizeof(tag)*(pos),SEEK_SET); Ret_S=fwrite(tag,sizeof(tag),1,Fp); return Ret_S; }

  • C言語のプログラムに関する質問です。

    C言語初心者で困っています。 SNをサンプリング数、FNをファイル数として、テキストファイルの1行目のデータ(kari[0])と2行目のデータ(kari[1])をそれぞれCH1、CH2に読み込むような以下のようなプログラムがあります。 ------------------------------------------ //読込みファイル名の設定// for(j=1;j<FN+1;j++){ sprintf(file_name,"%s%d%s",file,j,".txt"); printf("%d%s\n",j,file_name); if ((fp = fopen(file_name, "r")) == NULL){ printf("Error: Can't open file; %s\n", file_name); } //データの読込み// for(i=0;i<SN;i++){ fscanf(fp,"%lf,%lf\n",&kari[0],&kari[1]); ch1[i]=kari[0]; ch2[i]=kari[1]; } fclose(fp);       ・       ・       ・ fclose(fp); } ---------------------------------------------- しかし、テキストファイルの初めの3行には不必要な文字列が存在するため、4行目から読み込むように設定したいのですが、やり方がよく分かりません。 どのようにプログラムを書き換えれば良いか、教えていただけると助かります。 よろしくお願いします。

  • ファイルの入出力で困っています(C言語)

    はじめまして、nathan3と申します。 昔、さらっとC言語を学んでいたので、仕事場でも活用できればと思い、勉強しなおしています。 以下のプログラムですが、コンパイルはするものの、実行がなされません。 sprintfをつかってファイルを作り、fprintfで読み込み、countで繰り返し別名のファイルを読み込み・作成し…といったプログラムを書いているつもりです。 調べながら書いた稚拙なプログラムですが、ここがちがう!というところをお教えいただけると大変助かります。 #include <stdio.h> int main(void){ FILE *fp,*fo; char *fname1; char *fname2; char s[100],t[100]; int ret,count; for(count = 0 ; count < 3 ; count++) { sprintf(fname1, "sankasha%d.txt", count); fp = fopen(fname1, "r"); if (fp == NULL){ printf("%s can't open a file\n", fname1); return -1; } sprintf(fname2, "matome%d.txt", count); fo = fopen(fname2,"w"); if (fo == NULL){ printf("%s can't open a file\n", fname2); return -1; } printf("--fscanf---"); while( (ret = fscanf(fp,"%[^,],%s", s, t)) != EOF ){ fprintf(fo,"%s ", t); } } fclose(fo); fclose(fp); return 0; } 何度見直しても間違いが見つからず困窮しております。 どうぞ、みなさまのお力をお貸しください! よろしくお願いいたします。

  • プログラムが動きません。

    プログラムが動きません。 ファイルuniqipにはIPアドレスが書き込まれています。そのファイルからIPアドレスを文字列ipに格納します。 ファイルtmp4には、85.114.143.2 34f4ff4acb18802170a939ae42dcd5ee0eeccda4 のようにIPアドレスとハッシュ値が書き込まれています。 tmp4に現れるIPアドレスで、uniqipに一致するものに対応するハッシュ値を printf("file%d,%s\n",i,hash); の形で出力しようと思いましたが、うまくいきません。 何がまずいのでしょうか? #include <stdio.h> #include <string.h> //ひとつのIPアドレスに現れるユニークなハッシュ値の数をカウントする int main() { FILE *fp,*gp; char ip[269730][16]; char ip2[16]; char hash[42]; int i,j; fp = fopen("uniqip","r"); if(fp == NULL){ printf("can not open the file.\n"); return 1; } for(i=0;i<267930;i++) { fscanf(fp,"%s",ip[i]); //printf("%s\n",ip[i]); } fclose(fp); ////////////////////////////////////////////////////////////////////////////////////////////////////// gp = fopen("tmp4","r"); if(gp == NULL){ printf("can not open the file.\n"); return 1; } for(i=0;i<267930;i++){ for(j=0;j<2470766;j++){ fscanf(gp,"%s %s",ip2,hash); printf("%s\n",ip[i]); if(!strcmp(ip[i],ip2)) { printf("file%d,%s\n",i,hash); } } } return 0; }

専門家に質問してみよう