• ベストアンサー

構造体配列とポインタについて

いつもお世話になっています。 皆様には、本当にお世話になっています。 先日、皆様にアドバイスをいただいたのですが、私の勉強不足で結局・・・並び替えて表示できなかったです。 大変申し訳ないのですが、どこがダメなのか教えてください。 /********************/ /*--- 英単語辞書 ---*/ /********************/ #include <stdio.h> #include <string.h> #define NUMBER 50 /*登録数*/ #define MAX_NAME 20 /*単語の最大文字数*/ #define MAX_WAYAKU 30 /*和訳の最大文字数*/ /************************/ /*--- 単語帳の構造体 ---*/ /************************/ typedef struct { char name[MAX_NAME]; /*単語*/ char wayaku[MAX_WAYAKU]; /*和訳*/ }words; /***********************************************/ /*----- 単語の交換 -----*/ /***********************************************/ void swaps(words x, words y) { words temp = x; temp = x; x = y; y = temp; } /************************************************/ /*------ 単語と和訳の登録 ------*/ /* 関数tourokuword()は引数words tango[]の、イン*/ /*クリメントしたtango_counの順番に格納する。  */ /************************************************/ void tourokuword(words tango[], int tango_count) { char word[MAX_NAME]; /*単語の名前*/ char wa[MAX_WAYAKU]; /*単語の和訳*/ int i = 0; int j; printf("[単語]:"); scanf("%s", word); /*単語を単語帳に登録*/ strcpy(tango[tango_count].name, word); printf("[和訳]:"); scanf("%s", wa); /*和訳を単語帳に登録*/ strcpy(tango[tango_count].wayaku, wa); for( i = 0; i < tango_count; i++){ if(strcmp(tango[tango_count].name, tango[i].name) > 0){ swaps(tango[tango_count], tango[i]); } } } /***********************************************/ /*----- 登録された単語を表示する -----*/ /* 関数printword()は引数words tango[]の、イン */ /*クリメントしたtango_counの並び替えて表示する */ /***********************************************/ void printword(words tango[], int tango_count) { int i = 0; puts("登録されている単語を表示します。\n"); for (i = 0 ; i < tango_count; i++) { printf("[単語]:%s\n", tango[i].name); /*単語の表示*/ printf("[和訳]:%s\n", tango[i].wayaku); /*和訳の表示*/ } } /****************/ /*--- メイン ---*/ /****************/ int main(void) { words tangochou[NUMBER]; /*単語帳に50件登録*/ int menu_num; /*メニュー番号*/ int slct_num; /*選択番号*/ int tango_count = 0; /*登録数のカウント*/ while(1){ /****************************/ /*--- メニュー番号の入力 ---*/ /****************************/ do { printf("1・・・登録. 2・・・表示. 3・・・終了.\n"); printf("メニュー番号を入力してください。:"); scanf("%d", &menu_num); /*メニュ番号の入力*/ if (menu_num > 0){ break; } }while(menu_num != 0); /*メニュ番号が該当しない時は再入力*/ switch (menu_num){ case 1 :/*--- メニュー 1:単語と和訳の登録 ---*/ while(1) { if (tango_count < NUMBER){ printf("英単語と和訳を入力してください。:\n"); /*単語と和訳の登録*/ tourokuword(tangochou, tango_count); tango_count++; }else { puts("50件以上です。\n"); return 0; /*50件以上は終了する*/ } /*登録を続けるか?*/ printf("続けますか【Yes・・・1/No…0】:"); scanf("%d", &slct_num); if(slct_num != 1){ /*0なら終了。1なら継続。*/ break; } } break; case 2 :/*--- メニュー 2:登録された単語と和訳の表示 ---*/ printword(tangochou, tango_count); /*単語と和訳の表示*/ break; case 3 :/*--- メニュー 3:終了 ---*/ puts("終了します。\n"); return (0); default:/*--- メニュー 4:非メニュー番号の処理 ---*/ puts("メニュー番号が間違っています。"); break; } } return (0); }

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

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.15

>回答についてですが、質問があります。 >void swaps(words *x, words *y) >と、 >swaps(&tango[tango_count], &tango[i]); >は、もしかして、ポインタのポインタではないですよね? 違いますよ。ポインタのポインタはwords **xと書きます。 今回は必要ないので使っていません。今回のは、だたの構造体のポインタです。 >void swaps(words *x, words *y) >と、 >swaps(&tango[tango_count], &tango[i]); >修正し、実行してみましたが、並び替えられていません?? >どこがおかしいのでしょうか? これを↓表示の直前に移しましょう。その方が入力直後にソートするよりもプログラム的に簡単で分かりやすいと思います。それがうまく動いたら入力直後のソートに挑戦してみたらどうでしょう? for( i = 0; i<(tango_count-1); i++){ for( j = (i+1); j<tango_count ; j++ ) { if(strcmp(tango[i].name, tango[j].name) > 0){ swaps(&tango[i], &tango[j]); } } 元々書いていたのに近いものにしてみました。 このソートは、一番シンプルなソートの方法のうちの1つです。 まず、このソートを使いこなしましょう。 最後にソートの種類とアルゴリズムを紹介。 http://www.u-gakugei.ac.jp/~miyadera/LECTURE/SortAnim/ExAlgorithm.html http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%BC%E3%83%88 http://www1.cts.ne.jp/~clab/Contents/Sortindex.html

hatenan114
質問者

お礼

zwiさん、このたびは本当にありがとうございます。今日からは入門書を最初からしていきます。 次は社員名簿をリスト構造を使って作る予定なので、また宜しくお願いします。 これまでにみなさんが回答してくれたものを、確実に身に付けていきます。

その他の回答 (14)

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.14

あっ、ごめんなさい。hatenan114 「さん」が抜けてました^^;

hatenan114
質問者

お礼

mikaemiさん、このたびは本当にありがとうございます。 これまでにみなさんが回答してくれたものを、確実に身に付けていきます。 これからも宜しくお願いします。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.13

hatenan114は、既登録の単語はソートされてることを前提に、登録のところで、新しく登録する単語を一つだけ一重ループで挿入ソートっぽく挿入したいんだよね?^^

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

/********************/ /*--- 英単語辞書 ---*/ /********************/ #include <stdio.h> #include <string.h> #define NUMBER 50 /*登録数*/ #define MAX_NAME 20 /*単語の最大文字数*/ #define MAX_WAYAKU 30 /*和訳の最大文字数*/ /************************/ /*--- 単語帳の構造体 ---*/ /************************/ typedef struct {  char name[MAX_NAME]; /*単語*/  char wayaku[MAX_WAYAKU]; /*和訳*/ } words; /************************/ /*----- 単語の交換 -----*/ /************************/ void swaps( words *x, words *y ) {  words temp;    temp = *x;  *x = *y;  *y = temp; } /**************************/ /*----- 単語のソート -----*/ /**************************/ void sortword( words tango[], int tango_count ) {  int i, j;    for ( i = (tango_count - 1) ; i > 0 ; i-- ){   for ( j = 0 ; j < i ; j++ ){    if ( strcmp(tango[j].name,tango[j + 1].name) > 0 ){     swaps( &tango[j], &tango[j + 1] );    }   }  } } /************************************************/ /*------ 単語と和訳の登録 ------*/ /* 関数tourokuword()は引数words tango[]の、イン*/ /*クリメントしたtango_counの順番に格納する。  */ /************************************************/ void tourokuword( words tango[], int tango_count ) {  char buff[ 256 ];    /*単語を単語帳に登録*/  printf( "[単語]:" );  scanf( "%s", buff );  buff[ MAX_NAME - 1 ] = '\0';  strcpy( tango[tango_count].name, buff );  /*和訳を単語帳に登録*/  printf( "[和訳]:" );  scanf( "%s", buff );  buff[ MAX_WAYAKU - 1 ] = '\0';  strcpy( tango[tango_count].wayaku, buff ); } /***********************************************/ /*----- 登録された単語を表示する -----*/ /* 関数printword()は引数words tango[]の、イン */ /*クリメントしたtango_counの並び替えて表示する */ /***********************************************/ void printword( words tango[], int tango_count ) {  int i;    puts( "登録されている単語を表示します。\n" );    for ( i = 0 ; i < tango_count; i++ ){   printf( "[単語]:%s\n", tango[i].name ); /*単語の表示*/   printf( "[和訳]:%s\n", tango[i].wayaku ); /*和訳の表示*/   printf( "\n" );  } } /****************/ /*--- メイン ---*/ /****************/ int main( void ) {  words tangochou[ NUMBER ]; /*単語帳に50件登録*/  int menu_num; /*メニュー番号*/  int tango_count = 0; /*登録数のカウント*/    do {   /****************************/   /*--- メニュー番号の入力 ---*/   /****************************/   do {    printf( "\n" );    printf( "1・・・登録. 2・・・表示. 3・・・終了.\n" );    printf( "メニュー番号を入力してください。:" );    scanf( "%d", &menu_num ); /*メニュ番号の入力*/   } while ( menu_num <= 0 ); /*メニュ番号が該当しない時は再入力*/      switch ( menu_num ){    case 1:/*--- メニュー 1:単語と和訳の登録 ---*/     if ( tango_count >= NUMBER ){      puts( "50件以上です。\n" );      return 1; /*50件以上は終了する*/     }     printf( "\n英単語と和訳を入力してください。:\n" );     /*単語と和訳の登録*/     tourokuword( tangochou, tango_count );     tango_count++;     break;    case 2 :/*--- メニュー 2:登録された単語と和訳の表示 ---*/     sortword( tangochou, tango_count ); /*単語と和訳のソート*/     printword( tangochou, tango_count ); /*単語と和訳の表示*/     break;    case 3 :/*--- メニュー 3:終了 ---*/     puts("終了します。\n");     break;    default:/*--- メニュー 4:非メニュー番号の処理 ---*/     puts( "メニュー番号が間違っています。" );     break;   }  } while ( menu_num != 3 );    return 0; } ※インデント部は全角空白文字です。注意。 以上。

hatenan114
質問者

お礼

Oh-Orangeさん、このたびは本当にありがとうございます。 これまでにみなさんが回答してくれたものを、確実に身に付けていきます。 これからも宜しくお願いします。

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

★すべてのソースを手直しして動くようにしました。 ・何も修正しないでコンパイルするとワーニング(警告)が3つ表示されました。 >単語帳.cpp(40) : warning C4101: 'j' : ローカル変数は 1 度も使われていません。 >単語帳.cpp(87) : warning C4127: 条件式が定数です。 >単語帳.cpp(101) : warning C4127: 条件式が定数です。  ↑  tourokuword() 関数の j 変数は使っていないので削除すべき。  87、101行のはいずれも while(1) としているので for ( ; ; ) として無限ループを組むべし。 ・次に修正した関数と内容を解説。  (1)swaps() 関数に関しては他の回答者さんのアドバイス通りです。そちらを参考に。  (2)sort() 関数を追加しました。これがソート処理です。  (3)sort() 関数より tourokuword() 関数は登録するたびにソートしないようにしています。   scanf() 関数で直接構造体に文字列を入れている点に注目して下さい。  (4)printword 関数は int i = 0 の部分を int i; に修正しました。あと改行を入れました。  (5)main() 関数の while(1) を do-while に修正しました。  (6)main() 関数の do{ … } while ( menu_num != 0 ); を修正しました。break 部も削除。  (7)main() 関数の『単語と和訳の登録』部分を修正しました。続けますかとは表示し内容にした。  (8)main() 関数の『単語と和訳の表示』部分の前でソートをしています。その後表示。  (9)main() 関数の『メニュー終了』部分はメッセージのみで break します。その後do-while で抜ける。  以上の9箇所を修正しました。  次の回答でソースを載せますのでチェックしてみて下さい。  特にソート部分(swaps,sortword)と main() 関数全体を見て下さい。 ・以上。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.10

じゃあ、登録のところで、こうしますか? for( i = tango_count; i > 0; --i){ if(strcmp(tango[i-1].name, tango[i].name) > 0){ swaps(&tango[i-1], &tango[i]); } }

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.9

ん?登録のところで並び替えるのも、表示のところで並び替えるのも同じじゃないの?登録時は一個ずつ入れるので「挿入ソート」をつかって、表示の際は「シェルソート」使うとか? まぁそのうち、こなれてきてわかるようになると思いますよ。K&Rなどのよい言語の本と「アルゴリズムとデータ構造」などの本をじっくり理解していくのが、結局、早道かもしれませんが。。がんばってください^^

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.8

きゃはは^^ hatenan114 さん、おもしろいね^^ http://oshiete1.goo.ne.jp/qa3293885.html に残ってますよ(笑)

hatenan114
質問者

補足

ありがとうございます!!! でも・・・今回のソースは表示のところで並び替えず、登録時に並び替えたものなんです。 はぁ、7月からC言語をはじめたのですが、毎日が格闘です。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.7

hatenan114 さんが最初していたように、ソートするループを2重にしてください^^

hatenan114
質問者

補足

ループの部分がおかしいのですか?? 前のは、上書きしてしまい、わすれてしまいました。 すみません。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.6

swaps(tango[tango_count], tango[i]); と呼び出すと、 void swaps(words x, words y) に来る前に、 ・メモリ上にxが作られ、xにtango[tango_count]がコピーされる ・メモリ上にyが作られ、xにtango[i]がコピーされる と言う事が起きます。 で、xとyを入れ替えても、コピーが入れ替わるだけです。 ・その1 呼び出す部分を swaps(&tango[tango_count],&tango[i]); にして、関数を void swaps(words *x, words *y) { words temp = *x; *x = *y; *y = temp; } にする。 ・その2 呼び出す部分を swaps(tango,tango_count,i); にして、関数を void swaps(words tango[],int x, int y) { words temp = tango[x]; tango[x] = tango[y]; tango[y] = temp; } にする。 ・その3 インデックス配列を作成し、実体は入れ替えせず、インデックス配列のみを入れ替える。表示する時は、実体の順で表示せず、インデックス配列の順で表示する。 (このプログラムは回答に書きません。自作してみましょう) インデックス配列を用いる理由は以下の通り。 一番先頭に来る単語を最後に登録したらどうなるでしょう。50バイトもある配列が、49回も入れ替えされます。 単語数が50個なら問題無いですが、単語数が5000とかになったら? 構造体サイズが50バイトなら問題無いですが、文字数を増やして構造体が500バイトになったら?

hatenan114
質問者

お礼

ありがとうございます。 しかし、 修正し、実行してみましたが、並び替えられていません?? どこがおかしいのでしょうか?

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.5

>void swaps(words x, words y) >{ >words temp = x; > >temp = x; >x = y; >y = temp; >} なるほどわかりました。 原因はですね。値渡しとポインタによる参照渡しの違いを理解することが必要です。 >void swaps(words x, words y) と書くと呼び元の swaps(tango[tango_count], tango[i]); の実体をswaps関数に渡すのではなく、中身をコピーした新たなx,y構造体を作って渡すという意味なります。 つまり呼び出し時に、 words x = tango[tango_count]; words y = tango[i]; を暗黙に実行してコピーしています。 ですので、いくらx,yの中身を入れ替えてもコピーですので、元のtango[]側には影響がありません。 この場合は、 void swaps(words *x, words *y) と書いて swaps(&tango[tango_count], &tango[i]); で呼んでやるとポインタ渡しで実体のアドレスを受け渡すことが出来ます。ポインタの先はコピーではなく実体ですから、実体を書き換えることが出来るわけです。 void swaps(words *x, words *y) { words temp = *x; ポインタ先のxの実体をtempにコピー。 //temp = *x; ← 上の宣言で実行しているので不要です。 *x = *y; ← ポインタ先のyの実体をxの実体にコピー。 *y = temp; ← tempをポインタ先のyの実体にコピー。 } で交換がうまく出来るはずです。 前回は、色々いっぱい情報が入ってきて混乱しましたか? 他の人の意見も貴重なものが沢山ありましたので、1つずつ自分のものにしていってください。

hatenan114
質問者

お礼

本当に zwi 様には、頭があがらないです。 ありがとうございます。 一生懸命頑張りますので、宜しくお願いします。 回答についてですが、質問があります。 void swaps(words *x, words *y) と、 swaps(&tango[tango_count], &tango[i]); は、もしかして、ポインタのポインタではないですよね?

hatenan114
質問者

補足

void swaps(words *x, words *y) と、 swaps(&tango[tango_count], &tango[i]); 修正し、実行してみましたが、並び替えられていません?? どこがおかしいのでしょうか?

関連するQ&A

  • C言語 初心者

    コンパイルエラーはでないのに、 登録した単語を表示できません。 表示のところだと思うのですが・・・ /********************/ /*--- 英単語辞書 ---*/ /********************/ #include <stdio.h> #include <stdio.h> #define NUMBER 50 /*登録数*/ #define MAX_NAME 20 /*単語の最大文字数*/ #define MAX_WAYAKU 30 /*和訳の最大文字数*/ /************************/ /*--- 単語帳の構造体 ---*/ /************************/ typedef struct { char name[MAX_NAME]; /*単語*/ char wayaku[MAX_WAYAKU]; /*和訳*/ }words; /************************************************/ /*------ 単語と和訳の登録 ------*/ /* 関数tourokuword()は引数words tango[]の、イン*/ /*クリメントしたtango_counの順番に格納する。  */ /************************************************/ void tourokuword(words tango[], int tango_count) { char word[MAX_NAME]; /*単語の名前*/ char wa[MAX_WAYAKU]; /*単語の和訳*/ printf("[単語]:"); scanf("%s", word); /*単語を単語帳に登録*/ strcpy(tango[tango_count].name, word); printf("[和訳]:"); scanf("%s", wa); /*和訳を単語帳に登録*/ strcpy(tango[tango_count].wayaku, wa); } /***********************************************/ /*----- 単語の交換 -----*/ /***********************************************/ void swaps(words *x, words *y) { words temp = *x; strcpy(temp, *x); strcpy(*x, y); strcpy(*y, temp); } /***********************************************/ /*----- 登録された単語を表示する -----*/ /* 関数printword()は引数words tango[]の、イン */ /*クリメントしたtango_counの順番に表示する。  */ /***********************************************/ void printword(words tango[], int tango_count) { int i = 0; int j; puts("登録されている単語を表示します。\n"); for( i = 0; i < tango_count; i++){ for(j = i + 1; j < tango_count; j++){ if(strcmp(tango[i].name, tango[j].name) > 0){ swaps(&tango[i], &tango[j]); } } } for (i = 0 ; i < tango_count; i++) { printf("[単語]:%s\n",tango[i].name); /*単語の表示*/ printf("[和訳]:%s\n",tango[i].wayaku); /*和訳の表示*/ } } /****************/ /*--- メイン ---*/ /****************/ int main(void) { words tangochou[NUMBER]; /*単語帳に50件登録*/ int menu_num; /*メニュー番号*/ int slct_num; /*選択番号*/ int tango_count = 0; /*登録数のカウント*/ while(1){ /****************************/ /*--- メニュー番号の入力 ---*/ /****************************/ do { printf("1・・・登録. 2・・・表示. 3・・・終了.\n"); printf("メニュー番号を入力してください。:"); scanf("%d", &menu_num); /*メニュ番号の入力*/ if (menu_num > 0){ break; } }while(menu_num != 0); /*メニュ番号が該当しない時は再入力*/ switch (menu_num){ case 1 :/*--- メニュー 1:単語と和訳の登録 ---*/ while(1) { if (tango_count < NUMBER){ printf("英単語と和訳を入力してください。:\n"); /*単語と和訳の登録*/ tourokuword(tangochou, tango_count); tango_count++; }else { puts("50件以上です。\n"); return 0; /*50件以上は終了する*/ } /*登録を続けるか?*/ printf("続けますか【Yes・・・1/No…0】:"); scanf("%d", &slct_num); if(slct_num != 1){ /*0なら終了。1なら継続。*/ break; } } break; case 2 :/*--- メニュー 2:登録された単語と和訳の表示 ---*/ printword(tangochou, tango_count); /*単語と和訳の表示*/ break; case 3 :/*--- メニュー 3:終了 ---*/ puts("終了します。\n"); return (0); default:/*--- メニュー 4:非メニュー番号の処理 ---*/ puts("メニュー番号が間違っています。"); break; } } return (0); }

  • 教えてください。

    このソースの中で、間違えているところはどこですか? 誰か助けてください。 /* 英単語辞書の登録と表示 */ #include <stdio.h> #define NUMBER 50 /*登録数*/ /*--- 単語帳の構造体 ---*/ struct words { char name[20]; char wayaku[50]; }; /*--- 単語と和訳の登録 ---*/ struct words touroku_word(struct words tangochou[], char ) { int count = 0; char word[20],wa[50]; while(1) { printf("英単語を登録してください。:"); scanf("%s", word); strcpy(tangochou[],*s); count++; putchar('\n'); printf("和訳を入力してください。:"); scanf("%s", wa); strcpy(tangochou[],*s); putchar('\n'); if (i < NUMBER){ return (0); } if (cont == 0){ break; } } } /*--- 登録された単語を表示する ---*/ void print_word(struct words tangochou[],int count) { int i = 0; puts("登録されている単語を表示します。\n"); for (i ; i < count; i++) { printf("[単語]:%d\n",tangochou[i].name); printf("[和訳]:%d\n",tangochou[i].wayaku); } } int main(void) { struct words tangochou[2]; int menu; while(1){ do { printf("メニュー番号を入力してください。:"); scanf("%d", &menu); if (menu > 0){ break; } }while(menu != 0); switch (menu){ case 1 : touroku_word(tangochou[]); break; case 2 : print_word(tangochou[]); break; case 3 :puts("終了します。\n"); return (0); default :puts("メニュー番号が間違っています。"); break; } } return (0); }

  • 初心者です。

    いつもお世話になっています。 現在、ポインタと構造体と配列をつかって、構造体を使った単語帳を作成しています。以下のソースで、行き詰まってしまいした。 質問内容としては、今のソースから、単語と意味を登録するにはどうすればいいでしょうか?できれば、ポインタの使用時には、詳しく教えていただけないでしょうか。宜しくお願いします。 * 英単語辞書の登録と表示 */ #include <stdio.h> #define NUMBER 50 /*登録数*/ /*--- 単語帳の構造体 ---*/ struct words{ char name[20]; char wayaku[50]; }; /*--- 単語と和訳の登録 ---*/ /*--- 登録された単語を表示する ---*/ int main(void) { struct words name[] = {0}; struct words wayaku[] = {0}; char word = 0, wa = 0; char *p, *q; int menu; while(1){ do { printf("メニュー番号を入力してください。:"); scanf("%d", &menu); if (menu > 0){ break; } }while(menu != 0); switch (menu){ case 1 :printf("英単語を登録してください。:"); scanf("%s", word); p = &word; putchar('\n'); printf("和訳を入力してください。:"); scanf("%s", wa); q = &wa; putchar('\n'); break; case 2 :puts("登録されている単語を表示します。\n"); break; case 3 :puts("終了します。\n"); return (0); default :puts("メニュー番号が間違っています。"); break; } } ; return (0); }

  • 構造体

    下記プログラムの2次元配列を構造体の配列に作り変え,構造体を利用して生年月日の項目を追加し,形式は日を除いたYYYY/MMで持ち,生年月日の入出力は,YYYY/MM形式で行い,西暦が数字4桁で,西暦と月の間に'/'があり,月が01~12の範囲の数字の2桁になっている7文字の入力のみ受け付け,正しく入力されるまでそれ以外は再入力させたい。あとdo-while文をつかっている箇所をwhile文に直したいです.自力でやったのですが,わかりませんでした. どのようにしたらよいか教えてください. お願いします. include <stdio.h> #define BUFFERSIZE 11 #define MAX_PERSON 10 #define MAX_CHARS 10 int main(void) { char name[10][BUFFERSIZE]; int c; int count = 0; int i; int j; for (i = 0; i < MAX_PERSON; i++) { printf("氏名入力 : "); j = 0; /* 氏名の1文字目が'0'なら入力を終了 */ if ((c= getchar()) == '0'){ break; } if (c == '\n') { /* 改行のみの入力は再入力 */ do { printf( "再入力\n" ); /*再入力*/ printf("氏名入力 : "); } while ((c = getchar()) == '\n'); } name[i][j++] = c; /*1文字目を格納*/ if (name[i][0] == '0') { break; } while ((c = getchar()) != '\n' && c != EOF) { if (j < BUFFERSIZE - 1) { name[i][j++] = c; } } name[i][j] = '\0'; count++; /* 実際に入力した人数を記録*/ printf("累計 : %d \n", count); } /* 氏名と生年月日を出力したいです */ for (i = 0; i < count; i++) { for (j = 0; j < MAX_CHARS; j++) { if (name[i][j] == '\0'){ break; } putchar(name[i][j]); } putchar('\n'); } return 0; }

  • 構造体配列

    いつもお世話になっています。 今日構造体配列を勉強した際に下の演習をしていたのですが、いまいち基礎的な関数や配列のことやコマンドライン引数のことが理解できていません。一応自分なりにプログラムを書いてみたのですが、エラーがでます。 どなたかアドバイス・ご指摘・解説・例などをおねがいいたします。 問題はコマンドライン引数で人数を指定し,人数分のデータを標準入力(キーボード)から構造体配列に入力し,標準出力(ディスプレイ)に出力するプログラムです。 #include<stdio.h> typedef struct{ char name[100]; int age; double height; double weight; } PERSONAL_DATA1; typedef struct{ int person[10]; }PERSONAL_DATA2; PERSONAL_DATA1 input_personal_data(int num); void output_personal_data(PERSONAL_DATA2 person[10],int num); int main(int argc, char *argv[]){ PERSONAL_DATA1 x; int num,i; char person[10]; if(argc != 2){ printf("Usage ./test number"); return 0; } num=atoi(argv[1]); for(i=0;i<10&&i<num;i++){ person[i]=input_personal_data(); output_personal_data(person,num); return 0; } } PERSONAL_DATA input_personal_data(void){ PERSONAL_DATA1 x; printf("name>"); scanf("%c" ,&x.name); printf("age>"); scanf("%d" ,&x.age); printf("height>"); scanf("%lf" ,&x.height); printf("weight>"); scanf("%lf" ,&x.weight); return x; } void output_personal_data(PERSONAL_DATA2 person[10],int num){ PERSONAL_DATA1 x; printf("name>>%s\n" ,x.name); printf("age>>%d\n" ,x.age); printf("height>>%lf[cm]\n" ,x.height); printf("weight>>%lf[kg]\n" ,x.weight); } またコマンドライン引数で指定したデータファイルAから入力した個人データ集合を構造体配列に取り込み,標準出力(ディスプレイ)と同じくコマンドライン引数で指定したデータファイルBへファイル出力に出力するプログラムというおまけの問題もあります。 こちらの問題のヒントもいただけませんか?

  • 構造体の配列について

    構造体配列を使った簡単なプログラムを組んでいるのですが、以下のソースコードをコンパイルし、実行したのですが、うまくいきません。 どなたかお力をお貸しください。 ・やりたい事 配列に以下のようにデータをscanf関数を使って入れたいです。 ----[0]---[1]---[2]--- [0] 1 | "あ" | "猫" | [1] 2 | "い" | "亀" | [2] 3 | "う" | "狐" | -登録する内容 番号、名前、好きなもの動物 ■ソース #include <stdio.h> struct hyou { int box[3][3]; }; int main(){ struct hyou *da; int i; for(i=0;i<2;i++){ printf("番号:\n");   scanf("%d",&da->box[i][0]); printf("名前:\n");   scanf("%s",&da->box[i][1]); printf("好きなもの:\n");   scanf("%s",&da->box[i][2]); } //テスト(2件表示) for(i=0;i<2){ printf("番号:\n"); printf("%d",a->box[i][0]); printf("名前:\n"); printf("%s",a->box[i][1]); printf("好きなもの:\n"); printf("%s",a->box[i][2]); } } //構造体配列の意味が違っていたらすみません。 以上、宜しくお願いします。

  • プログラミング構造体について。

    include<stdio.h> #include<stdlib.h> #include<string.h> struct person{ char name[10]; int gender; int age; }; void printPersonList(struct person *person_p, int size); void outputPersonList(struct person *person_p, int size); double getAverageOfAge(struct person *person_p, int size); int countMales(struct person *person_p, int size); int countFemales(struct person *person_p, int size); int main(void){ struct person *person_p; int i, count, gender, age, maleCount, femaleCount; char name[20]; double average; printf("登録する人数を入力してください。\n"); scanf("%d", &count); person_p = (struct person*)malloc(sizeof(struct person)* count); for(i=0; i < count; i++){ printf("名前・性別(男性:0, 女性:1)・年齢をスペース区切りで入力してください。\n"); scanf("%s %d %d", name, &gender, &age); strcpy((person_p + i) -> name, name); (person_p + i) -> gender = gender; (person_p + i) -> age = age; } printPersonList(person_p, count); outputPersonList(person_p, count); average = getAverageOfAge(person_p, count); printf("平均年齢:%f\n", average); maleCount = countMales(person_p, count); femaleCount = countFemales(person_p, count); printf("男性:%d名, 女性:%d名\n", maleCount, femaleCount); free(person_p); return 1; } void printPersonList(struct person *person_p, int size){ int i; printf("登録リスト\n"); printf(" name | gender | age\n"); printf("----------+--------+-----\n"); for(i=0; i < size; i++){ printf("%10s | %1d | %2d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } } void outputPersonList(struct person *person_p, int size){ FILE *output; int i; if((output = fopen("meibo.c", "w")) == NULL){ printf("meibo.cを開けませんでした。\n"); return; } for(i=0; i < size; i++){ fprintf(output, "%s, %d, %d\n", (person_p + i) -> name, (person_p + i) -> gender, (person_p + i) -> age); } fclose(output); } 残り3つの関数をすべて定義する(それぞれ10行程度) getAverageOfAge, countMales, countFemales どう定義すればいいのか教えてください。お願いします。

  • C言語 構造体でつまずいています

    以下、番号と点数を入力して構造体配列に入力し、番号に0が入力されたら、入力処理をやめ、平均点を表示するプログラムです。  今のコードでは、最初から番号に0を入力すると、0除算になりエラーになります。どうすれば良いのでしょうか? #include <stdio.h> #define MAX 50 //配列の要素数を定義 int count=0; //グローバル変数 struct data { //構造体の定義 int num; //メンバの宣言 int ten; }; void nyuryoku(struct data *); //プロトタイプ宣言 float heikin(struct data *); //プロトタイプ宣言 void main() { struct data score[MAX]; //構造体の宣言 printf("**学生番号/点数入力**\n"); printf("\n"); nyuryoku(score); //nyuryoku関数呼び出し printf("\n**以上%d名の平均点:%0.1f点**\n",count,heikin(score)); //heikin関数の戻り値表示 } //nyuryoku関数 //機能:構造体配列にデータを入力する void nyuryoku(struct data *pd) //仮引数pdに構造体ポインタが渡る { int i; for(i=0;i<MAX;i++){ printf("学生番号>>"); scanf("%d",&pd->num); if(pd->num==0){ //学生番号に0を入力するとループを抜ける break; } printf("点  数>>"); scanf("%d",&pd->ten); count++; //人数のカウント pd++; //構造体配列を一つずらす } } //heikin関数 //機能:構造体配列の点数の平均を計算、戻り値として返す float heikin(struct data *pd) //仮引数pdに構造体ポインタが渡る { int i; int sum=0; float ave=0; for(i=0;i<MAX;i++){ if(pd->num==0){ break; } else{ sum+=pd->ten; //点数を加算 pd++; } } ave=(float)sum/count; //平均値を求める return(ave); //平均値を戻り値として返す }

  • ポインタ配列で、、。

    #include <stdio.h> #define NUM 3 main (void) { char *c = {"cup"}; char *cc[NUM], a0 = 'L', a1 = 'A', a2 = 'P'; char *ccc[NUM] = {"hat","bat","cat"}; int i; cc[0] = &a0; cc[2] = &a1; cc[2] = &a2; printf("c -----> %s\n", c); for(i = 0; i < NUM; i++) { printf(" cc[%d] -> %c\n", i, *cc[i]); } for(i = 0; i < NUM; i++) { printf("ccc[%d] -> %s\n", i, ccc[i]); } for(i = 0; i < 3; i++) { printf("ccc[0][%d] --> %c\n", i, ccc[0][i]); } } /* わたしの実行結果です c -----> cup cc[0] -> L Press any key to continue */ これはどういうことをしているプログラムなのでしょうか?どうかお願いします。

  • 構造体についてです。

    身体測定表を作っていて最初に作ったデータを変更して表示したいのですがNo1の168cm→162cm No2の74kg→74.5kg  No3の20歳→19歳 No4の田中三郎→小林三郎 (No3と4は構造体ポインタを使ってデータを変更) 全データを表示させてその後No1と3の名前~体重を丸ごと入れ替えて全データを表示させたいのですがエラーがでてしまいます。 分かる人がいましたらどこを直したらいいか教えて下さい。 #include <stdio.h> #include <string.h> struct data{ int no; char name[21]; int age; int height; float weight; }; struct data *sp; void main(){ int i; struct data a[4]={ {1,"鈴木太郎",23,168,60}, {2,"山本次郎",17,180,74}, {3,"山田花子",20,156,53}, {4,"田中三郎",35,172,68}, }; struct data b; for(i=0;i<4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i]. weight); } a[0].height=162; a[1].weight=74.5; *sp[2].age=19; strcpy(*sp[3].name,"小林三郎"); for(i=0;i<=4;i++){ b=a[0]; a[0]=a[2]; a[2]=b; a[0].no=1; a[2].no=3; } for(i=0;i<=4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i].weight); } }

専門家に質問してみよう