• 締切済み

固定長レコードから構造体について_C言語

固定長レコードから構造体について フラットファイルから固定長のレコードを取得して 構造体に格納する。 という内容なんですが、構造体指定バイトのデータを格納して 求めている結果が... kozo_a:aaaaa kozo_b:bbbbb kozo_c:ccccc となって欲しいのですが、 構造体の確認をしてみたところ... list[0]: kozo_a:aaaaabbbbbccccc kozo_b:bbbbbccccc kozo_c:ccccc list[1]: kozo_a:aaaaabbbbbccccc kozo_b:bbbbbccccc kozo_c:ccccc list[2]: kozo_a:aaaaabbbbbccccc kozo_b:bbbbbccccc kozo_c:ccccc list[3]: kozo_a:aaaaabbbbbccccc kozo_b:bbbbbccccc kozo_c:ccccc のように、求めている結果と異なってしまいます。 未だ問題解決しておらず、誰かお力を貸して頂けないですか? ~input(ファイル名)~ 01:aaaaabbbbbcccccdddddeeeeefffff 02:aaaaabbbbbcccccdddddeeeeefffff 03:aaaaabbbbbcccccdddddeeeeefffff ~ソース~ /*test.c*/ /********************************/ /* include */ /********************************/ #include <stdio.h> /********************************/ /* マクロ */ /********************************/ #define FILE_NAME "input" /* 入力ファイル名 */ #define LISTMAX 5 /* レコードMAX件数 */ #define MAX_LEN 128 /* 1行の最大文字数 */ /* 入力ファイルカラム定義 */ #define colum_a 5 #define colum_b 5 #define colum_c 5 #define colum_d 5 #define colum_e 5 #define colum_f 5 /********************************/ /* 宣言 */ /********************************/ int i=0; /* カウンタ */ FILE *fp; /* FILEポインタ */ char buff[MAX_LEN]; /********************************/ /* 構造体 */ /********************************/ struct shohin { char kozo_a [colum_a]; char kozo_b [colum_b]; char kozo_c [colum_c]; char kozo_d [colum_d]; char kozo_e [colum_e]; char kozo_f [colum_f]; }; struct shohin list[LISTMAX]; /********************************/ /* メイン処理 */ /********************************/ int main(void) { /********************************/ /* ファイルオープン */ /********************************/ fp=fopen(FILE_NAME,"r"); /********************************/ /* データ入力処理 */ /********************************/ while(NULL!=(fgets(buff,MAX_LEN,fp))) { if(i==LISTMAX) { /* レコード件数がLISTMAX(5)を超えた時 */ printf("確保した以上にデータがあります\n"); break; } sscanf(buff,"%s %s %s", list[i].kozo_a, list[i].kozo_b, &list[i].kozo_c); printf("list[%d]:\n\tkozo_a:%s\n\tkozo_b:%s\n\tkozo_c:%s\n", i, list[i].kozo_a, list[i].kozo_b, list[i].kozo_c); i++; } fclose(fp); } //▲▲▲▲▲▲▲▲▲▲▲▲▲▲ //最終的に私が求めているのは、 //あるファイルのデータから、nバイト目~nバイト目を //構造体を用いて判定して、その部分の指定データを置換(変換)する。という課題です。 //イメージ //変換前:aaaaaBBBBBcccccddddd //変換後:aaaaabbbbbcccccddddd //行き詰ってしまい先が見えません…お力を貸してください!

みんなの回答

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

#1です。 本題とはちょっとはなれたところの疑問なんですが、 質問者さんはCOBOLの経験者だったりしませんか? 提示されているプログラムをよーく見ていると、それとなくCOBOL臭がするんですが… Cを使うならCOBOLのことはあまり引きずらないほうが良いと思います。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★いきなりサンプルを載せます。 ●ヘッダ部 struct shohin1 {  char kozo_a[ 5 ];  char kozo_b[ 5 ];  char kozo_c[ 5 ];   :  char kozo_f[ 5 ]; }; struct shohin2 {  char kozo_a[ 5 + 1 ];  char kozo_b[ 5 + 1 ];  char kozo_c[ 5 + 1 ];   :  char kozo_f[ 5 + 1 ]; }; ●ソース部 struct shohin1 list[ LISTMAX ]; struct shohin2 data; int i, max; // 読み込み部 max = fread( list, sizeof(struct shohin1), LISTMAX, fp ); // フィールド分割処理 for ( i = 0 ; i < max ; i++ ){  struct shohin *p = &list[i];    sprintf( data.kozo_a, "%.*s", sizeof(p->kozo_a), p->kozo_a );  sprintf( data.kozo_b, "%.*s", sizeof(p->kozo_b), p->kozo_b );  sprintf( data.kozo_c, "%.*s", sizeof(p->kozo_c), p->kozo_c );   :  sprintf( data.kozo_f, "%.*s", sizeof(p->kozo_f), p->kozo_f );    // 置換前の表示部  printf( "置換前:%.*s\n", sizeof(struct shohin1), p->kozo_a );    // 置換(変換)部  if ( !strcmp(data.kozo_b,"BBBBB") ){   memcpy( p->kozo_b, "bbbbb", sizeof(p->kozo_b) );  }  // 置換後の表示部  printf( "置換後:%.*s\n\n", sizeof(struct shohin1), p->kozo_a ); } 解説: ・固定長レコードの構造体へのセットは『fread』関数で簡単に行えます。  問題は『kozo_a』メンバの次に『kozo_b』メンバの文字列が NULL 文字で区切らずに  連続している事です。そこで、for 文で文字列の分割用の構造体(struct shohin2)に  コピーしています。この分割用の構造体を利用して置換(変換)を行って下さい。 ・あと fopen、fclose の部分は省略しました。 ・以上。おわり。

参考URL:
http://www9.plala.or.jp/sgwr-t/lib/fread.html,http://www9.plala.or.jp/sgwr-t/lib/memcpy.html
  • Werner
  • ベストアンサー率53% (395/735)
回答No.2

> sscanf(buff,"%s %s %s", list[i].kozo_a, list[i].kozo_b, &list[i].kozo_c); ANo.1でも言われていますが、 ここは質問者さんの意図通りに動作していないと思います。 最初の%sでbufの内容がほぼ全部読み込まれてlist[i].kozo_aに格納され、 残りの%sでの読み取りは失敗してます。 結果的に、sscanf(buff,"%s", list[i].kozo_a); としたのと同じことになってます。 list[i].kozo_aはsizeof(char)*5の領域しか確保されてないので、 list[i].kozo_aに格納しようとした内容は kozo_b以降のメンバや、次のshohin構造体にあふれてしまいます。 そのため、struct shohinの定義でメンバの順番を入れ替えたり、 間に別のメンバを入れたりすると挙動が変わると思います。 (正しく作っているなら、メンバ順を入れ替えても動作は同じはずです。) なお、scanfの%sでも読み取り文字数は > sscanf(buff,"%5s%5s%5s", list[i].kozo_a, list[i].kozo_b, &list[i].kozo_c); とすれば制限できますが、 '\0'の分の領域が足りていないのであふれることに変わりはありません。 '\0'終端の文字列として格納する気がないなら、そもそも%sで取得するべきではないですね。 (もっとも、'\0'終端文字列として扱いたいのか、 単なるバイト列として扱いたいのか質問者さんの文章からはよく分かりませんでしたが。) > //あるファイルのデータから、nバイト目~nバイト目を > //構造体を用いて判定して、その部分の指定データを置換(変換)する。 やりたいのが本当にこれだけなら、そもそも構造体使う必要性が低い気がします。 それと気になったのですが、なぜ変数をmain関数内で宣言していないのでしょうか グローバル変数にする必要性はなさそうなのですが? あと、main関数の最後のreturnを忘れてますよ。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

sscanf(buff,"%s %s %s", list[i].kozo_a, list[i].kozo_b, &list[i].kozo_c); ここで sscanf の戻り値を確認してみてください。 多分質問者さんの期待するのとは違う値になっているはずです。 で構造体が struct shohin { char kozo_a [colum_a]; char kozo_b [colum_b]; char kozo_c [colum_c]; char kozo_d [colum_d]; char kozo_e [colum_e]; char kozo_f [colum_f]; }; この定義だと kozo_a と kozo_b (後に続くものも同様)は 連続していますよね。そこにきて各配列メンバーの末尾に ナルバイトが入っていないので list[0]: kozo_a:aaaaabbbbbccccc kozo_b:bbbbbccccc kozo_c:ccccc こうなると。 レコードもフィールドも固定長なら、sscanfなんて持ち出さないで 直接格納してしまえばいいのでは? 各メンバーの終端をどう処理するか を考える必要はありますが。 そもそもこのレコードをフィールドに分割する必要があるんでしょうか? ほかにもいろいろ指摘したいところはありますがこのくらいにしておきます。

関連するQ&A

  • C言語の構造体で悩んでます。

    構造体で顧客情報を管理する課題に取り組んでいるんですが、言語は苦手な分野で解決しかねてます。みなさんの力を借りたいです。お願いします。 課題は、構造体で顧客情報を確保(顧客情報入力の前に、キーボードで1~50の顧客情報の数を入力し、その数の構造体を確保)し、その後、顧客情報を登録するというものです。 私が記述したのは下記のとおりです。 間違いだらけだと思います。すみません。 #define size_id (5) #define size_name (25) #define size_huri (25) #define size_tel (17) struct kokyaku { long *id; char *name; char *huri; char *tel; }; int main() { int a , i; // 構造体確保の数、構造体参照時使用 long c = 1; // id struct kokyaku *ko; printf("顧客情報がありません。何件分確保しますか?(1 - 50)"); scanf("%d",&a); ko = (struct kokyaku *)malloc( sizeof(struct kokyaku) * (a)); if(a >= 1 || a <= 50) { for(i = 0;i < a;i++){   ko[i].id = (long*)malloc(size_id);   ko[i].name = (char*)malloc(size_name);   ko[i].huri = (char*)malloc(size_huri);   ko[i].tel = (char*)malloc(size_tel);       } }else{ printf("<<入力範囲にありません>>\n"); printf("<<処理を中断します>>\n"); return 0; } while(c <= a) {  i = 0;  printf("***** 顧客登録画面 *****\n");  ko[i].id = &c;  printf("氏名  :");  scanf("%s", ko[i].name);  printf("ふりがな:");  scanf("%s", ko[i].huri);  printf("電話番号:");  scanf("%s", ko[i].tel);  c++;  i++; } } エラーとか特にないのですが、構造体を件数分確保できていないと思います。 この後にも削除やファイル出力といった展開をさせなければならないのですが、後はなんとか自力でがんばろうと思います。 乱文ですみません。 よろしくお願いします。

  • C言語についてアドバイスをください。

    CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou *o) { printf("%d\n%s\n",o->nenrei,o->namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 short i = 0; int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); } fread(buff, 1, NUM, fp); while(buff1[n] != NULL) { buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。 if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { i = (short)atoi(buff2); // char型からshort型への変換 p.nenrei = i; } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ------------------------------------------------------- 今のままだと 『11 11,名前1 11 11,名前1 15,名前2』 という表示になってしまいます。 while 内で既に読み込んだ部分を読み込ませないよう(表示させないよう)にできたら良いと思うんですが、そういったやり方はあるのでしょうか? むしろやり方を変えたほうが良いでしょうか・・・。 まだC言語を学び始めて日が浅いので、色々間違っている部分もあると思いますが、 そういったことを含めてアドバイスをいただけたらと思います。 よろしくお願いします。

  • C言語について教えてください。

    数日前に「http://okwave.jp/qa4903738.html」で質問させてもらった者です。 前回、寝起きでボケてるうちに回答を締め切ってしまって、 回答してくださった方との対話ができていませんでした。 すみません。 今回は前回の指摘された部分を含めて回答を戴きたく投稿させてもらいます。 質問内容はほぼ変わりありません。 CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 あと、fgetsは使わないようにしたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ----------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou o) { printf("%d\n%s\n",o.nenrei,o.namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); return 1; } fread(buff1, 1, NUM, fp); // ここでファイルの内容が全てbuffに入る。 // printf("%s\n",buff1); // buff1にファイルの内容が書き込まれているか確認する。 while((buff2[n] = buff1[n]) != NULL) // buff2[0]からbuff1の中が終わるまで一文字ずつコピーしていく。 { if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { p.nenrei = atoi(buff2); // char型からshort型への変換し、p.iAgeに入れていく。 } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ----------------------------------------------- 前回指摘されたwhileの条件式ですが、 まだchar型とポインタを比べてることになっているので正しくないんですよね? 正直、どうすればいいかわかりません。 あと、今のままでは名前3の後が改行ではないので表示されることないですよね・・・。 どうすれば表示されるようになるでしょうか。 これも前回言われましたが while内の1つ目のif文の所で、カンマを処理したので次に取り込むbuff2への書き込み位置の変更というのもわかりません。 カンマが来た時点でbuff2[n]のnは2になっているんですよね? ということはbuff2[3]からまた読み込めたらいいということですよね? 厚かましくも立て続けに質問してしまって申し訳ありませんが回答を戴けたらありがたく思います。 宜しくお願いします。

  • C言語 構造体、関数 質問です。

    下のプログラムは、ファイルに書いてある、姓と名のデータを 構造体にもたせ、それぞれ出力させるというものです。 これの応用として、関数を使って構造体にデータをもたせる プログラムに改良したいのですが、よくわかりません。 根本的なものはあまり変わらないと思っているのですが、 どなたか、詳しくアドバイスお願いします。 #include<stdio.h> #define dFamilySize(32) #define dNameSize(32) #define dPersonSize(1024) #define dBufferSize(64) typedef struct _PROFILE PROFILE; struct _PROFILE { char family[dFamilySize]; char name[dNameSize]; }; main() { int i,j,k; char line[dBufferSize]; PROFILE list[dPersonSize]; for(i=0; i<dPersonSize; i++){ list[i].family[0]='\0'; list[i].name[0]='\0'; } i=0; while(fgets(line,dBufferSize,stdin)!=NULL){ for(j=0; line[j]!=' '; j++){ list[i].family[j]=line[j]; } list[i].family[j]='\0'; for(k=0,j++; line[j]!='\0'; j++,k++){ list[i].name[k]=line[j]; } list[i].name[k]='\0'; printf("%s\n",list[i].family); i++; } }

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • c言語構造体に関するプログラム

    データファイルをコマンドラインから読み込み、元のファイルの内容に加えその平均と評価を出力するプログラムを作っているのですが、実行しても意味のわからない文字が羅列され更に平均等が0になってしまいます。 分かる方いらっしゃいましたら回答よろしく願いします<(_ _ )> ↓読み込むデータファイルの内容 1077001 Jack 87 70 71 92 91 1077002 Jo 67 77 75 92 71 1077003 Akira 37 60 71 52 36 (中略) 1077016 Kazu 95 97 90 95 98 以下、ソースコード #include <stdio.h> #include <stdlib.h> typedef struct{ char sid[8]; char sname[10]; int score[5]; char grade; double ave; } Record; char grade_char(double); int main(int argc, char *argv[]){ Record data[20]; FILE *fp; int i; if((fp = fopen(argv[1],"r")) == NULL){ printf("Cannot open file!\n"); exit(1); }else if(argc == 1) printf("Error! Usage: ./a.out datafilename"); i = 0; while(fscanf(fp,"%s %s %d %d %d %d %d",data[i].sid,data[i].sname,&data[i].score[0],&data[i].score[1],&data[i].score[2],&data[i].score[3],&data[i].score[4])){ i++; data[i].ave = (data[i].score[0]+data[i].score[1]+data[i].score[2]+data[i].score[3]+data[i].score[4])/5; data[i].grade = grade_char(data[i].ave); printf("%s %s %d %d %d %d %d %.1f %c\n",data[i].sid,data[i].sname,data[i].score[0],data[i].score[1],data[i].score[2],data[i].score[3],data[i].score[4],data[i].ave,data[i].grade); } fclose(fp); return 0; } char grade_char(double ave){ if(0 <= ave && ave <= 34)return 'F'; else if(35 <= ave && ave <= 49)return 'D'; else if(50 <= ave && ave <= 64)return 'C'; else if(65 <= ave && ave <= 79)return 'B'; else if(80 <= ave && ave <= 100)return 'A'; else return 0; }

  • C言語でコマンドmvを実行

    name.txtというテキストファイルがあり、中身は 123 abc 456 def … となっています。 このテキストファイルを1行ずつ読み込んで、 mv 123/ abc/ のようにテキストファイルの中身に沿って、ディレクトリの名前を一気に変更したいのですが、上手くいきません。 どこがおかしいか、教えていただけないでしょうか。 /* header files */ #include <stdio.h> #include <stdlib.h> /* main */ int main(int argc, char *argv[]) { char *buff; float ret, ter; char a[50],b[50]; FILE *fp, *fq; fp = fopen(argv[1], "r"); while((ret = fscanf(fp,"%s %s",a,b)) != EOF){ sprintf(buff, "mv %s %s",a,b); system(buff); } fclose(fp); return EXIT_SUCCESS; }

  • c言語プログラムについて

    http://www.post.japanpost.jp/zipcode/dl/kokagi.html から全国一括(1,735,160Byte)をダウンロード このファイルを使って、 Linuxマシン上で、 例えば、北海道札幌市中央区旭ケ丘 と入力すれば、0640941 と返却されるプログラム(引数はコマンドラインで)をcで作成したいと思っているのですが、ファイルのダウンロードとファイルの読み込みまでは出来たのですが、その後の「北海道札幌市中央区旭ケ丘 と入力すれば、0640941」からが分かりません。どなたか続きを教えて頂けないでしょうか? 使用OS:fedora 一応、ソースを載せておきます #include <stdio.h> int main(void){ FILE *fp; char *fname="ken_all.csv"; char d[100]; char e[100]; char f[100]; char g[100]; char h[100]; char i[100]; int ret,a,b,c; fp = fopen("ken_all.csv", "r"); if (fp == NULL) { printf("ファイルをオープンできませんでした\n",fname); return -1; } while( (ret = fscanf( fp, "%[^, ],%d,%d,%s,%s,%s,%s,%s,%s", &a, &b, &c, d, e, f, g, h, i ) ) != EOF ){ printf( "%d %d %d %s %s %s %s %s %s", a, b, c, d, e, f, g , h , i); } fclose(fp); return 0; }

  • C言語 構造体

    以前にも構造体について質問させていただきましたが、より自由度の高い処理が必要となりご質問させていただきます。 よろしくお願いいたします。 以前のものは入力する項目数(列),行数(行)が前提にあるものでした。 テキストファイルを読み込んで、 構造体としてデータを読み込みたいのですが、 今回は項目数が不定のものです。 a.txt ------------------------- あああ,いいい,ううう ------------------------- とあれば あああ いいい ううう とカンマ抜きで得たい。(3項目) 次回読み込んだとき、 a.txt ------------------------- abc,def,g,h,i,jk ------------------------- とあれば、 abc def g h i jk とカンマ抜きで得たい。(6項目) 以前のものは下記のような感じです。 FILE *fp; FILE *file; struct seiseki seito[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); i=0; while( fgets(buf, sizeof(buf), fp) ){ struct seiseki tmp; sscanf(buf,"%d %s %s %d %d %d",&tmp.no,tmp.lname,tmp.fname,&tmp.val[0],&tmp.val[1],&tmp.val[2]); seito[i++] = tmp; } for(i = 0; i < 3; i++) { printf("%d / %s %s / %d / %d / %d / %d\n", seito[i].no,seito[i].lname,seito[i].fname, seito[i].val[0], seito[i].val[1], seito[i].val[2], seito[i].val[0] + seito[i].val[1] + seito[i].val[2]); }

  • C言語 構造体(2)

    ご質問です。 構造体で、あらかじめメンバ数を固定したものではなく、 テキストファイルを読み込んだときにメンバ数を変えて読み込みたいのです。 (カンマできりたい) aaa.txt ------------------------ あああ,いいい ------------------------ となっているときは、 tmp.nm[0]=あああ tmp.nm[1]=いいい となり、 kamoku.nm[0] kamoku.nm[1] をprintf。 aaa.txt --------------------------- あああ,いいい,ううう,えええ --------------------------- の場合は tmp.nm[0]=あああ tmp.nm[1]=いいい tmp.nm[2]=ううう tmp.nm[3]=えええ kamoku.nm[0] kamoku.nm[1] kamoku.nm[2] kamoku.nm[3] をprintf。 下記は動きません。。 よろしくお願いいたします。 #include <stdio.h> struct kamokumei { char nm[10]; }kamoku; int main(void) { int i,P,t; FILE *fp; struct kamokumei kamoku[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); P=3; t=0; while( fgets(buf, sizeof(buf), fp) ){ struct kamokumei tmp; sscanf(buf, "%s", tmp.nm[t]); nm[t++] = tmp; } for(i = 0; i < P; i++) { printf("%s\n", kamoku.nm[i]); } return 0; }

専門家に質問してみよう