• ベストアンサー

ファイル操作

あるファイルから長さの違った数字や文字を読み込んで配列に格納したいのですが数字などの長さが違うとなんかおかしくなってしまいます; 例えば 1 a 1 2 a 2 3 b 3 4 b 4 などのファイルはできるのですが 0 1 2 3 a 3 4 b 4 5 c 5 の場合5つの配列に格納したいのです。1行目で1つ2行目で1つ3行目の 左、真ん中、右の数字でそれぞれ1つづつ格納したいのです。 それで自分でやったのですが typedef struct path{ int left [100]; int right[100]; char center [100]; }Path; int main(int argc,char *argv[]) { FILE *fp; Path path; int i=0; int first; int second[100]; fp = fopen(argv[1],"r"); while(fscanf(fp,"%d %c %d",&path.left[i],&path.center[i],&path.right[i])==3){ i++; } fclose(fp); このようにやると3行目からはきちんとよみこむのですが1、2行目がうまくできません@@; firstとsecondのそれぞれ1、2行目を入れたいのです。 fscanfをもう1つ増やすしてもやってみましたがうまくいきませんでした。 ちなみにfscanf関数のところをならったばかりです。 fgetcとかそのようなのを使うのでしょうか?(よくわからないですけど) よろしくお願いします。ちなみにLinuxでgcc、C言語です。

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

  • ベストアンサー
  • tanma3
  • ベストアンサー率58% (14/24)
回答No.2

こんな感じで同でしょう? #include<stdio.h> #include<stdlib.h> #include<memory.h> #include<ctype.h> typedef struct path { int left; int right; char center; }Path; Path Split(char *pinter, int checkLen); int main(int argc,char *argv[]) { FILE *fp; Path path[100]; char tempBuffer; int lengthCounter; int seekOffset; int dataSetOffset; char *pTemp; int counter;  fp = fopen(argv[1], "r"); // 初期化 lengthCounter = 0; seekOffset = 0; dataSetOffset = 0; counter = 0; memset(path, 0, sizeof(path)); while((tempBuffer = (char)fgetc(fp)) != EOF) { lengthCounter++; if(tempBuffer == '\n') { // メモリ確保 pTemp = (char*)malloc(lengthCounter); if(pTemp != NULL) { fseek(fp, seekOffset, SEEK_SET); fread(pTemp, 1, lengthCounter, fp); *(pTemp + (lengthCounter-1)) = '\0'; // split path[counter++] = Split(pTemp, lengthCounter); // メモリ解放 free(pTemp); // 読込み開始位置更新 seekOffset += (lengthCounter + 1); lengthCounter = 0; } else { printf("fails in the memory securing."); break; } } } if(lengthCounter != 0) { } fclose(fp); } Path Split(char *pinter, int checkLen) { int i; int count; int numType; Path tempPath; char *pTemp; int number; memset(&tempPath, 0, sizeof(Path)); pTemp = malloc(checkLen); if(pTemp != NULL) { memset(pTemp, 0, checkLen); numType = 1; count = 0; number = 0; for(i=0; i<checkLen; i++) { if((*(pinter+i) != '\0') && (*(pinter+i) != ' ')) { *(pTemp + count) = *(pinter+i); count++; if(isdigit(*(pinter+i)) == 0) { numType = 0; } } if((*(pinter+i) == ' ') || (*(pinter+i) == '\0')) { if(numType == 1) { if(number++ == 0) tempPath.left = atoi(pTemp); else tempPath.right = atoi(pTemp); } else { tempPath.center = *pTemp; } // 再初期化 numType = 1; count = 0; memset(pTemp, 0, checkLen); } } free(pTemp); } return(tempPath); }

senkei777
質問者

お礼

こ、こんなに長くなるんですね@@; 一度コンパイルしてどのように動くか考えたいと思います! 回答ありがとうございます<(_ _)>

その他の回答 (1)

  • gonbee774
  • ベストアンサー率38% (198/511)
回答No.1

1行を文字列として読んで、 その文字列を解析する。 (何文字でこうさいされているか、2番目が数字か否か、など?) その解析結果(あるいは解析しながら)所望の変数にとり込む。 で、できそうな気がします。

senkei777
質問者

お礼

回答ありがとうございます<(_ _)> あんましぱっとこないのでよく考えてみます@@;

関連するQ&A

  • おしえて

    #include <stdio.h> #include <stdlib.h> int a[30000][6]; int main(int argc, char *argv[]) { FILE *fp; int c,n,i,j; if ((fp = fopen(argv[1], "r")) == NULL) { printf("File Open Error.\n"); exit(1); } for(i=0;i<30000;i++){ for(j=0;j<6;j++){ c = fscanf(fp, "%d", &n); if (c) { a[i][j]=c; printf("%d ",a[i][j]); } } printf("\n"); } fclose(fp); return 0; } このプログラムを書きましたna.txtのファイルが以下のようなとき 1 2 3 4 5 6 3 4 5 6 7 8 のとき先頭の1しか配列に格納できません。どうしても順番にa[0][0~5]=1~6と入れたいです。どうしてもわかりません。おしえてください!!

  • C言語でファイルの内容を strtok関数 を使って数字と文字を分けて

    C言語でファイルの内容を strtok関数 を使って数字と文字を分けて配列に格納したいのですが、うまくできません。 どこが駄目なのかご指摘をお願いします! ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int i=0; int num[10]; char na[10]; fp=fopen(argv[1],"r"); while(fgets(str,sizeof str,fp)!=NULL); tp = strtok ( str, " " ); while(tp != NULL ) { num[i]=atoi(tp); tp = strtok( NULL," "); if ( tp != NULL ){ na[i]=*tp; } i++; } printf("%d\n%s",num[0],na[0]); printf("%d\n%s",num[1],na[1]); fclose(fp); return 0; }

  • エラーが出ます

    12,51,13,123,133,551,… というコンマで区切られているファイルを読み込みたいです。数字は100文字です。どう書けば全部読み込めるでしょうか? よろしくお願いします。 int main(int argc,char *argv[ ]){ int line; int i; FILE *fp; fp = (argc > 1)? fopen(argv[1],"r"): stdin; if(fp==NULL){ perror("fopen"); exit(0); }   while(fscanf(fp,"%d",&line) != EOF){ printf("%d\n") } if(argc>1){ fclose(fp);   }

  • C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問

    C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問です! ファイルを開いた後でエラーとなるのですが、何が足りないのでしょうか? ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int k,i=0; int num[10]; char na[10][20]; fp=fopen(argv[1],"r"); if(fp==NULL){ printf("ファイルを開けません\n"); return 1; }else{ printf("開けた\n"); } while(fgets(str,sizeof str,fp)!=NULL){ tp=strtok(str," "); num[i]=atoi(tp); tp=strtok(NULL," "); strcpy(na[i],tp); i++; } printf("%d\n%s\n",num[0],na[0]); printf("%d\n%s\n",num[1],na[1]); fclose(fp); return 0; }

  • ファイル読み込みが上手くできません

    C言語初心者です。 現在、ファイルの情報を構造体に読込んで実行するプログラムを作成しております。 読込むファイルは700MBほど(行数は39900000行)となっており、1行ずつfscanfで読込んでいます。 400000行ごとに構造体に読込んで、処理を実行し、構造体に読込んだ全ての処理が完了したら、再度400000行読込んで・・・を繰り返すものになっております。 400000行ごとにしているためforループで100回まわすようにしているのですが、最後の1回(100回目のループ)で、99回目と同じ場所を読んできてしまいます。 つまり、最後の1回だけはファイルポインタが進んでいない状況になります。 コードは下記になります。 #define MAX_SIZE 400000 uint64_t i = 0; uint64_t fc = 0; int main(int argc, char *argv[]){ char w[] = "$write"; char r[] = "$read"; // ファイルを構造体へ格納 char filename[] = "TEST_READ_WRITE.txt"; struct TEST_DATA{ char cmd[10]; int addr; int bsize; }; FILE *fp; if ((fp = fopen(filename, "r")) == NULL){ printf("%s open error !\n", filename); exit(1); } for (int lp = 0; lp < 100; lp++){ struct TEST_DATA TD[MAX_SIZE]; // 構造体配列の宣言 for (fc = 0; fc < MAX_SIZE; fc++) { if (feof(fp)){ break; } else{ fscanf(fp, "%s %d %d\n", TD[fc].cmd, &TD[fc].addr, &TD[fc].bsize); } } while (i < MAX_SIZE - 1){ //ファイルから取得したデータによって処理を実行 if (strcmp(TD[i].cmd, w) == 0){ //書込み処理 } if (strcmp(TD[i].cmd, r) == 0){ //読み込み処理 } } printf("Finish!! \n"); } fclose(fp); return 0; } 読込むファイルはテキストデータで、 $write 25651496 152 $write 135878112 8 $read 1244848 16 のような感じのものが39900000行並んでいるものになります(数字はランダムです)。 最後の1回のみ上手くファイルポインタが進まない原因が分からずに困っています。 お気づきの方がいらっしゃいましたら、アドバイスをよろしくお願いします。

  • 配列のサイズ変更

    FILE *fp; char *fname = "test.txt"; unsigned char init[300]; int i = 0; int c; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } while( (c = fgetc( fp )) != EOF ){ init[i] = c; i = i+1; } fclose( fp ); 自分のプログラムの中のこのようなテキストから文字を読んで配列に格納するような動作の中で、initを大きめにとっておいて配列に格納し終わったら余った空の配列を削除する、という機能を拡張したいのですがどのようにすればいいかわかりません。 どなたか教えていただけないでしょうか?

  • 【C】引数の変換をする場合どちらの方法を使うべきでしょうか?

    int main(int argc, char* argv[]) { int i; /* argv[1]をintになおして格納用 */ 処理 } という感じでメインを作ると思いますが 引数のargv[0]はファイルの絶対パス argv[1]には"必ず"数字(整数)が入っていると仮定して argv[1]をint型に変換する場合 (1) sscanf(argv[1], "%d", &i); とするか (2) stdlib.hをインクルードして i = atoi(argv[1]); とするかの二通りをとりあえず思いついたのですが どちらもintに変換された値が入るわけですが C言語になれておられる方なら普通どちらをつかいますか? (1)or(2) 又はそれ以外の方法、どっちでも良し、場合によるetc... ご意見よろしくお願いします。

  • C言語・ファイルと文字列の操作プログラムについて!

    ファイルのデータを1行ずつ読み込み、","で区切られた要素に分割して配列に格納するプログラムの作り方を教えてください。 下記のようなファイルがあり、各行の3つめの要素の数字(ハイフンを含む)を各行で比較し、昇順に行をソートするというプログラムを作成しております。 要素数は4つめ以降各行ばらばらです。 [ファイル test.txt] 2013/08/01,16:19,20130801161906-210164001071,,,川口,神奈川,,電話番号 2013/08/01,11:32,20130802003256-116091178056,鈴木,埼玉,mail,電話番号 2013/08/01,15:55,20130801155519-119072194140,,,山田,東京,mail まず、ファイルを読み込み、3つめの要素を下記のように配列s[i]に格納しようとしたのですが、うまく配列に3つめの要素がはいってくれません。 strtokを用いたプログラムを作っているのですが、1行ずつ分割と表示はできるものの、それを配列に格納することができなくて困っております。 配列の格納にstrcpyを用いたところ、途中でプログラムが強制終了し、配列への格納ができませんでした。 [格納の例] s[0]=20130801161906-210164001071 s[1]=20130802003256-116091178056 s[2]=20130801155519-119072194140 [自分のプログラム] #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 300 int main() { char filename[] = "test.txt"; FILE *fp; char data[MAX], *words[MAX],*s[MAX],*cp; const char *delim=","; int g,i=0,j,len; // ファイル・オープン if ((fp = fopen(filename, "r")) == NULL) { printf("ファイルのオープンに失敗\n"); exit(1); } while (fgets(data, MAX, fp) != NULL) //1行読み込む { cp = data; for (len = 0; len < MAX; len++) { if ((words[len] = strtok(cp, delim)) == NULL) //","で文字列を分割 break; cp = NULL; } s[i] = words[2]; //3つ目の要素を配列に格納 i++; } for(j=0;j<3;j++){ //表示 printf("%s\n",s[j]); } [実行結果] 20130801155519-119072194140 20130801155519-119072194140 20130801155519-119072194140 プログラムの訂正箇所,上記と異なるプログラム,大体の流れ… などなんでもかまいませんので、教えていただきたいです。よろしくお願いします。

  • 末尾の行が二回読み込まれてしまいます。

    末尾の行が二回読み込まれてしまいます。 以下のコードで #include <stdio.h> #include <stdlib.h> //ファイルに書き込まれた24:00:00の形式の時刻を秒単位で出力する。 int translate(char* str) { int a,b,c; int time; sscanf(str,"%d:%d:%d",&a,&b,&c); time = 60*60*a + 60*b + c; return time; } int main(int argc,char *argv[]) { FILE *fp; char str[100]; int s; fp = fopen("file.time","r"); if(fp == NULL){ printf("can not open the file.\n"); return 1; } while(!feof(fp)){ fscanf(fp,"%s",str); s = translate(str); printf("%d\n",s); } fclose(fp); return 0; } 末尾の行が二回処理されてしまいます。なにがまずいのでしょうか?よろしくお願いいたします。

  • ファイルポインタによるコアダンプの解決法

    タイトルの通りです。以下のプログラムを実行するとコアダンプがでるので、解決法を教えて頂きたいです。 5つのdatファイルの読み込みはうまくいきました。15個に増やしたところ、コアダンプが表示されました。 ファイルポインタを使わずに実行してみたら15個でも大丈夫でしたので、ファイルポインタが原因かと思います。 typedef struct{ int class; int** matrix; }pattern_struct; int main(int argc,char* argv[]) { pattern_struct *learn; FILE *fp; int width,height; int i,j,k,value; learn=(int*)malloc(argc*sizeof(int)); //ファイルからの学習データの読み込み for(k=1;k<argc;k++){ fp=fopen(argv[k],"r"); printf("%s\n",argv[k]); printf("学習する数字を入力してください "); scanf("%d",&learn[k].class); fscanf(fp,"%d %d",&width,&height); learn[k].matrix=(int**)malloc(height*sizeof(int*)); for(i=0;i<height;i++) learn[k].matrix[i]=(int*)malloc(width*sizeof(int)); for(i=0;i<height;i++){ for(j=0;j<width;j++){ fscanf(fp,"%d",&value); learn[k].matrix[i][j]=value; } } fclose(fp); fp=NULL; } return 0; }