- ベストアンサー
C言語で文字配列の問題がわかりません
初めて質問します。最近、C言語の勉強をし始めた者ですが、今回「20字以上の行を全て印字せよ。」という演習プログラムを書いています。 専門書の方では文字配列の単元の演習問題なのですが、例題を参考にして以下にここまでは自力で書きました。しかしこのソースコードに対して実行したところ、どうやら「20字以上ある行の、次の行」が印字されているようで、全く原因がわかりません。 putcharの使用が必須だったのですが、試しに関数putlineを消して printf("%s",line); で出力してみるとうまくいきました。どうやら関数putlineに問題があると思っているのですが(ここは完全に自力だったため^^;)、ご指摘、アドバイス頂けると光栄です。 よろしくお願いしますm(_ _)m #include<stdio.h> #define MAXLINE 1000 int getline (char s[], int lim) { int c,i; for (i=0; i<lim-1 && (c=getchar()) !=EOF && c!='\n'; i++){ s[i]=c; } if (c= ='\n'){ s[i]=c; i++; } s[i]='\0'; return i; } int putline (char t[]) { int c,i; for (i=0; (c=getchar()) !=EOF && c!='\n'; i++){ t[i]=c; putchar(t[i]); } if (c= ='\n'){ t[i]=c; putchar(t[i]); } return 0; } main() { int len; char line[MAXLINE]; while( (len=getline(line,MAXLINE) )>0 ){ if (len>20){ putline(line); } } }
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
・コメント文がない 演習問題といえども、日頃からコメントを付加する習慣を つけたほうがいいですよ。 人の書いたプログラムなんて初見では意味不明です。 ・インデントがない プログラムが非常に見づらく感じます。 あと、問題の原因は putline関数の中でline配列に新たに文字列を入力している為です。 確認ですけど、getline関数が文字列を入力し、 putline関数が文字列を出力する関数ですよね? ならputline関数の中でgetcharしなくてもいいはずです。
その他の回答 (7)
- yaha_2007
- ベストアンサー率21% (13/61)
特に無いと思います。 頑張ってください
- asuncion
- ベストアンサー率33% (2127/6289)
> 配列tから一文字ずつ取り出す 配列tのn番目の要素を取り出すときは t[n] と書きます。
お礼
度々のアドバイスありがとうございます。 関数、配列についてまだ理解できていない点が多々あるので、よく学んで行きたいと思います。
- yaha_2007
- ベストアンサー率21% (13/61)
老婆心ながら一つ忠告しておきますが 「なんとなく」や「イメージ」ではプログラムは作れません。 ちゃんと関数の機能やアルゴリズム、仕様を理解して作ってください。 たとえ”まぐれ”で上手くいったとしても、 中身の分からないプログラムは無価値です。 とりあえず、どこがどのように分からないのか 示していただかないと、答えようがありません。 もうちょっと情報ください。
補足
確実に理解していくように努めます。 関数getlineとmainの部分は理解できています。分からない部分は関数putlineのなかで、「配列tから一文字ずつ取り出す。」という部分でした。これまでの演習で、getcharとputcharは関数内で同時に使われる、つまり int c; c = getchar(); while (c != EOF) { putchar( c ); c = getchar(); } という感じでputcharの前には必ずgetcharがなくてはならないのだと勘違いをしていました。 みなさんからの指摘を受けこのように書き換えてみました。 int putline (char t[ ]) /*関数の宣言*/ { int n; for (n=0; t[n] != '\0'; n++){ /*'\0'まで配列tを一文字ずつとりだす*/ putchar( t[n] ); /*配列tの出力*/ } return 0; } 結果うまくいったようです。シンプルにまとめることができたと思うのですが、もっと明確にすべきところはありますでしょうか?
- yaha_2007
- ベストアンサー率21% (13/61)
#2です。 インデント消えるんですか!知らなかったスイマセン >putline内にgetcharは必要ないとのことでしたが、どのように >putcharを用いたらよろしいんでしょうか? 初心者で本当にお手数 >おかけします^^;;; そちらのプログラムの正確な仕様が分からないので 関数名から推測して暫定的にお答えします。 putline関数の中ではputcharは必要ありません。 >「20字以上ある行の、次の行」が印字されている この場合印字されている文字列を獲得しているのはgetline関数でなく putline関数だと思われます。 おそらく目指しているのは (1)getlineで文字列取得 (2)20文字以内ならputlineで表示 という仕様だと思います。 しかし、getcharをputline内においた場合 せっかくgetline関数で取得した文字列を それが20文字以上だった場合、putline関数で再度取り直しています。 その結果、問題が生じています。
補足
問題が起きてる部分は何となくですが、その原因が理解できました。 >おそらく目指しているのは >(1)getlineで文字列取得 >(2)20文字以内ならputlineで表示 はい、その通りです。配列tから一文字ずつ取り出す、というイメージもわかるのですが、取り出す=「getchar」しか浮びませんでした。 違いますよね^^; もう少しご教授頂けますか?
- asuncion
- ベストアンサー率33% (2127/6289)
putline()で、出力すべきデータは配列tに入っています。 tから1文字ずつ取り出し、putchar()してください。 1文字ずつ取り出すのが終わるのは、'\0'が見つかったときです。
- asuncion
- ベストアンサー率33% (2127/6289)
> ・インデントがない > プログラムが非常に見づらく感じます。 仮に、元のソースがタブやスペースできちんとインデントしていたとしても、 アップロードした時点できれいさっぱり消えてしまいます。残念なことですけれど。 例えば全角スペースを使えば、アップロード結果はインデントしているように見えますが、 そうするとそのままコピー&ペーストしたのではコンパイルできない、 という痛しかゆしの状態です。
お礼
asuncionさんの仰る通りです^^; コピーペーストの結果、かなり見にくくなってしまったのに気付かなくて…すいませんでした。 初めての投稿だったもので、コメント文がないなど、気が付かなくてこれもまたすいませんでした。これから気をつけたいと思ってます。 putline内にgetcharは必要ないとのことでしたが、どのようにputcharを用いたらよろしいんでしょうか? 初心者で本当にお手数おかけします^^;;;
- asuncion
- ベストアンサー率33% (2127/6289)
putline関数の機能(役割分担)は何でしょうか? getline関数で入力を受け持っている上に、 さらにputline関数で入力を行なう必要はあるのでしょうか? putline関数は、引数で受け取った内容を出力する、 という機能に特化すべきではないでしょうか。
お礼
わかりました。ありがとうございます^^ Cを学び始めてから日が浅いですが、自力で考えることを忘れずに精進します。