• ベストアンサー

配列とfor文の組み合わせがうまくいきません

初心者なので質問文でおかしなことを言ってるかもしれませんが よろしくお願いします ソースは下に貼り付けました。 コースの数を入力し、そのコースに名前をつけるという プログラムを書いたのですが forでcoursename[0]からcoucename[3]までの4つに名前を入力しようと コース数に「4」を入力しても forによって繰り返されるのは coursename[0]からcoucename[2]までの3つでした どう直せばいいのでしょうか ==================================================== #include <stdio.h> #define MAX_COURSE 5 /*最大数*/ int main(void){ int course = 0; /*コース数*/ char coursename[MAX_COURSE][100]; /*コース名*/ char line[100]; /*入力用文字型配列*/ int i; /*コース数の入力*/ while (course < 1 || 5 < course){ printf("コース数の入力を行ってください。(1~5)\n"); printf("INPUT : "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &course); } /*コース名の入力*/ printf("コース名の入力を行ってください。\n"); for(i=0; i<course-1; i++){ printf("%d科目 : ", i+1); fgets(line, sizeof(line), stdin); sscanf(line, "%s" , coursename[i]); } return 0; } ====================================================

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

  • ベストアンサー
  • arain
  • ベストアンサー率27% (292/1049)
回答No.2

>コース数に「4」を入力しても >forによって繰り返されるのは >coursename[0]からcoucename[2]までの3つでした > for(i=0; i<course-1; i++) なんだから、courseに「4」を入力したら for(i=0; i<(4-1); i++)  ↓ for(i=0; i<3; i++) となるから、0~2までで正しい。 というか、「1」を入力した時点でおかしいのがわかるはずだし、 他の数で出こまで表示されるかで法則性もすぐにわかるはず。

その他の回答 (3)

  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.4

forが繰り返されるのは条件式が「真」である間だけ。 iの値と式の結果を表にして 条件が正しいか検証してごらん なぁに、ほんの0~4までしかないし すぐすぐ ほんとは いくないんだけど表の最初だけ書いておいてあげるよ ------------------- course=4 i : i<course-1 ---+------------ 0 : true

moll77s
質問者

お礼

回答ありがとうございます。 基本的な算数の部分で間違えてました 本当にお恥ずかしい

  • okg00
  • ベストアンサー率39% (1322/3338)
回答No.3

for(i=0; i<course-1; i++){ courceが4の場合、for文で条件を満たすのは0,1,2しかないですから当然です。この場合、 for(i=0; i<course; i++){ for(i=0; i<=course-1; i++){ のどちらかとする必要があります。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.1

>for(i=0; i<course-1; i++){ course-1 と書いているのはなぜですか? このコードでは、courseが4のとき、iは0, 1, 2の順に変化します。

moll77s
質問者

お礼

回答ありがとうございます お恥ずかしことに不等号の意味がわかっておりませんでした 以後気を付けます

関連するQ&A

  • プレゼント交換プログラム

    クリスマスパーティーのプレゼント交換のためにプログラムを書いているのですがなかなか上手くいきません。下に実装したい機能(僕の考えた解決策)と僕の書いたコードを載せておくのでアドバイスをお願いします。よろしくお願いします。 実装したい機能(僕の考えた解決策) 1.自分の持ってきたプレゼントが自分に当たらないようにする (プレゼントの番号と配列に格納する順番を一致させれば解決できると 思うのですが…) 2.全員の手にプレゼントが渡るようにする (全ての数字(例えば参加者が5人なら0~4)が割り振られたことを確認し満たしていなければやり直しにすれば解決できると思ったのですが…) ---コードここから--- #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void){ char line[100]; /* キーボード入力用汎用変数 */ int participant; /* 参加者数 */ int flag = 0; int i, j; srand(time(NULL)); /* 参加者数を入力する */ printf("参加者数: "); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &participant); int number[participant]; /* プレゼントの番号 */ char name[participant]; /* 参加者の名前 */ int check[participant]; /* チェック用配列 */ /* */ for(i = 0; i < participant; i++){ printf("参加者 %d 人目の名前: ", i + 1); fgets(line, sizeof(line), stdin); sscanf(line, "%s", &name[i]); } /* */ do{ for(i = 0; i < participant; i++){ number[i] = rand() % participant; check[i] = number[i]; } for(j = 0; j < participant; j++){ for(i = 0; i < participant; i++){ if(check[i] == j){ flag += 1; } } } }while(flag != participant); /* */ for(i = 0; i < participant; i++){ printf(" %s ―\―\>プレゼント %d\n", name[i], number[i] + 1); } return 0; } ---コードここまで---

  • 2次元配列への標準入力

    初めまして。 私は今C言語のプログラミングを勉強しています。 2次元配列へ文字列の標準入力を行い、それをプリントさせるという問題を考えています。(配列の行の要素はMAXに達しなくても空行が入力されたら 終了させたい。) 下のようなプログラムを書きましたが、空行を入力してプリントする際に 文字が崩れてしまって上手く表示されませんでした。 初歩的で恐縮ですが、どのように改善したら良いか、 教えて頂けたら嬉しいです。 #include <stdio.h> #include <ctype.h> #define MAX 10 int main(){ char array[MAX][MAX]; int i; for(i = 0; i < 10; i++){ fgets(array[i],sizeof(char)*MAX,stdin); if(array[i][0] == '\n') break; } for(i = 0; i < 10; i++){ printf("%s", array[i]); } return 0; }

  • 単語数、文字数のカウントプログラム

    以下のような単語数、文字数のカウントプログラムを作ったのですが、10行目に「フォーマットは char ですが、引数は different type です」というエラーが出てしまいます。どのように修正したらよいでしょうか?教えてください。 #include <stdio.h> int main(void){ int wordcnt = 0; int charactercnt = 0; int i; char line[100]; printf("String: "); fgets(line, sizeof(line), stdin); sscanf(line, "%s", &line); if(line[0] != ' '){ wordcnt++; } for(i = 0; line[i] != '\0'; i++){ if(line[i - 1] == ' '){ wordcnt++; } if(line[i] != '\n'){ charactercnt++; } } if(wordcnt == 1){ printf("%d word,", wordcnt); }else{ printf("%d words,", wordcnt); } if(charactercnt == 1){ printf(" %d character", charactercnt); }else{ printf(" %d characters", charactercnt); } return 0; }

  • C言語で 数字を配列に入力し,q Qで終了させたい

    O.reillyのC実践プログラミング第3版で、勉強しています。 p105の 実習7-6 「いくつかの数字が入力されたとき、正の数がいくつあるか、負の数がいくつあるかを  数えるプログラムを作成せよ」に取り組んでみました。    例えば 「1 -1 2 -2 3 -3 -4 -5 で8つの数があり、正が3 負が5を出力させたい」のです。  入力の終わりは、q,Qで、終了させたいと考えました。  でも、「8個の数字を配列に入力させq、Qで入力終了」のところがうまくいきません。  次のようなプログラムで行き詰まっています。  どこを手直しすればいいのか教えて下さい。 #include <stdio.h> #include <math.h> #define KOSU 10 /*入力できる個数*/ char line[10];/*入力した数を受けるためのバッファ*/ int plus_count = 0;/*プラスカウンター*/ int minus_count = 0;/*マイナスカウンター*/ int number[20]; int given_number; int i; int main(void) { printf("+、ーの数を 入れなさい。(最大20まで)\n 終わるときは、qを入れる\n"); { for(i = 0; i < KOSU; i++) { fgets(line, sizeof(line), stdin); sscanf(line, "%d", &given_number); number[i] = given_number; /*ここからした、qを入れるとそこで終了のはずがうまく動きません 10個入れたらちゃんと終わるのですが。*/ if ( (given_number == 'q') || (given_number == 'Q') ) break; } } for(i = 0;i < KOSU;i++) { printf("number[%d] = %d \n", i, number[i]); } /*正負の数を数えることにする。*/ for(i = 0;i < KOSU;i++) { if(number[i] > 0) plus_count++; else minus_count++; } printf("plus is %d\n",plus_count); printf("minus or zero is %d\n",minus_count); }

  • なぜエラーになるのでしょう。

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define STR_MAX 512 #define LINE_MAX 30000 int main(void){ // ※↓がエラー原因※ char str[LINE_MAX][STR_MAX]; printf("%d\n", sizeof(int)); printf("%d\n", sizeof(int[10])); printf("%d\n", sizeof(char[10])); printf("%d\n", sizeof(char[STR_MAX])); printf("%d\n", sizeof(char[LINE_MAX])); printf("%d\n", sizeof(char[LINE_MAX][STR_MAX])); printf("%d\n", sizeof(long[STR_MAX][LINE_MAX])); printf("%d\n", sizeof(str)); return 1; } というプログラムを実行すると「問題が発生したため~を終了します。ご不便をかけて~」という問題が発生して終了してしまいます。 原因は、 printf("%d\n", sizeof(str)); の部分であるのですが、 char str[LINE_MAX][STR_MAX]; という宣言でメモリ使用量が大きすぎるということでしょうか? しかし、 printf("%d\n", sizeof(char[LINE_MAX][STR_MAX])); printf("%d\n", sizeof(long[STR_MAX][LINE_MAX])); でも正常に実行できているのに・・・ もともとは、何万行もあるテキストファイルを配列に一度格納し、それらを編集して出力しようと思っていたのですが、毎回エラーが発生するので、調べたところ配列宣言の部分 char str[LINE_MAX][STR_MAX]; にエラーがあるということが分かったのですが、原因が分かっても理由がさっぱり分かりません。 googleで配列の上限について調べたり、仕様について調べたのですが、ほしい回答が得られず質問させてもらいました。 分かる方いましたら教えてください。 ちなみにExcelのマクロを組んだときにdim StrTemp(512, 30000) as stringと宣言して Option Explicit Function SampleTest() Dim StrTemp(512, 30000) As String Dim i, j As Integer For i = 1 To 512 For j = 1 To 30000 StrTemp(i, j) = "SampleTest" Next j Next i End Function と処理をすることはできたので、パソコンのメモリ容量が足りないとは思えないのです。

  • fgetsとループ処理

    C言語の勉強をしております。 http://oshiete1.goo.ne.jp/qa4436782.html での質問に付随することなのですが、新しく立てさせていただきました。 キーボードからの入力で、何も入力されない場合にループから抜けたいんですが、以下のように記述すると、fgetsが飛ばされてしまいました。 char buffer[80]; int i; for(i = 0; i < 1000; i++){ memset(buffer, 0, sizeof(buffer));   printf("登録する名前を入力してください:"); fgets(buffer, sizeof(buffer)-1, stdin); /* 名前が未入力でEnterされた場合 */ if(buffer[0] == '\n'){ /* ループを抜ける */   break;   } } sscanf(buffer, "%s", work_pt->names); 1回目のループで未入力とすると正常にループから抜けるんですが、 データを1度入力してから2回目の入力で未入力とすると、 「登録する名前を入力してください:」の表示後、ループから抜けてしまいます・・・。 どなたか原因と解決策の分かる方がおられたら教えていただけないでしょうか?

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • ファイルの内容の表示

    実行時のコマンドライン引数で指定したファイルの内容を、行番号付きで画面に表示するプログラムを作る という問題です。ヒントも与えられています。 行番号付きの表示、コマンドライン引数の利用。両者を組み合わせればできるはずだ >  main関数の引数にargcとargvを指定して、コマンドライン引数をファイル名として利用する。キーボード入力を促す文(プロンプト)や改行チェックは不要なので書かないこと >  コマンドライン引数が指定されない場合は、メッセージを表示してプログラムを終了 >  ファイルの内容を画面表示する処理は、ユーザー定義関数put_file_contentsに記述する。仮引数には文字型のポインタ変数をひとつ指定し、ファイル名を受け渡せるようにする。put_file_contents自体の型は整数型(int)で、正常終了なら返り値0を返すこと。 行番号付きのプログラム#include<stdio.h> > int put_file(char *filename); > > int main() > { > char line[50]; > char *ptr; > > printf("ファイル名を入力:"); > fgets(line,sizeof(line),stdin); > ptr = line + strlen(line) - 1; > if(*ptr == '\n') { > *ptr = '\0'; > } > > put_file(line); > > return 0; > } > > int put_file(char *filename) > { > FILE *fp; > char buf[100]; > int line_no; > > fp = fopen(filename,"r"); > if (fp == NULL){ > printf("%sを開けません\n",filename); > return 1; > } > line_no = 1; > while (fgets(buf,sizeof(buf),fp) != NULL){ > printf("%3d: ",line_no); > printf("%s",buf); > line_no++; > } > fclose(fp); > > return 0; > } で、コマンドライン引数のプログラムは#include<stdio.h> void write_key_inputs(char *filiname); int main(int argc, char *argv[1]) { write_key_inputs(argv[1]); return 0; } void write_key_inputs(char *filename) { FILE *fp; char buf[100] ; fp = fopen(filename,"w"); while(fgets(buf, sizeof(buf),stdin) != NULL) { fputs(buf, fp); } fclose(fp); return ; } です。これらを組み合わせて少しいじると出来るみたいなのですが、できていません。ちなみに私が考えたプログラムは #include<stdio.h> int put_file_contents(char *filename); int main(int argc,char *argv[]) { int i; if(argc == 1){ printf("コマンドライン引数がありません\n"); return 1; } for(i = 0;i<argc;i++) printf("argv[%d]は「%s」です\n",i,argv[i]); put_file(i); return 0; } int put_file(char *filename) { FILE *fp; char buf[100]; int line_no; fp = fopen(filename,"r"); line_no = 1; while (fgets(buf,sizeof(buf),fp) != NULL){ printf("%3d: ",line_no); printf("%s",buf); line_no++; } fclose(fp); return 0; } です。コマンドライン引数は表示されるのですが、行番号が表示されません。どうしたらいいでしょうか??

  • fgets, sscanf, バッファ、ストリーム について

    ファイルからデータを入力するのに、fscanf の代わりに fgets と sscanf を用いようと考えています。 そこで、sscanf に与えるバッファ文字列を、ファイルストリームのように扱う方法は無いものでしょうか。 例えば以下のデータファイルに対して、以下のプログラムをうまく動作させるには、どのようにすればよいでしょうか。 どうぞ、よろしくお願いします。 (データファイル test.dat) n_data 4 1 3 8 4 (プログラム) #include <stdio.h> main() { int i, n_data, *data; char buf[100]; FILE *fp; fp = fopen ( "test.dat", "r" ); fgets(buf, 100, fp); sscanf( buf, "n_data %d\n", &n_data ); data = (int *)malloc( n_data * sizeof(int) ); for( i=0; i<n_data; i++ ){ fgets(buf, 100, fp); sscanf( buf, "%d", &(data[i]) ); } sscanf( buf, "\n" ); close( fp ); printf( "n_data %d\n", n_data ); for( i=0; i<n_data; i++ ) printf( " %d", data[i] ); printf( "\n" ); } ちなみに、2行の fgets(buf, 100, fp); をコメントアウトして、 "sscanf( buf," を "fscanf( fp," に変更するとうまく動作します。

  • 作成したいプルグラムがあります。

    実は作成してみたいプログラムがあります。 それは単語カウントプログラムです。 入力するテキストのファイル中の単語(大文字小文字区別なし)を数えて、そして全体の単語数&それぞれの単語ごとの数を表示させるプログラムを作成してみたいです。分かりやすく言いますと以下の通りです。 This is a pen. This is a book. を入力すると、 total:8 This :2 is:2 a:2 pen:1 book:1 と出力されるプログラムです。 今までやってみてできた段階は #include <stdio.h> int main(void) { char s[256]; char t[256]; int i, n[3] = {0, 1, 0}; int j, o[3] = {0, 1, 0}; /* 標準入力より文字列を取得 */ printf(""); printf(""); fgets(s, sizeof s, stdin); fgets(t, sizeof t, stdin);      /* 文字列内の単語数を取得*/ for (i = 0; s[i]; i++) if (s[i] == ' ') /* 単語の区切りは空白文字*/   n[1]++; for (j = 0; t[j]; j++) if (t[j] == ' ') /* 単語の区切りは空白文字*/   o[1]++;      printf("total:%d\n\n", n[1]+o[1]);      return(0); } です。これ以降は分からなくて、参考になれるご指導をお願いいたします。

専門家に質問してみよう