初めて質問します。最近、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);
}
}
}
No.2ベストアンサー
- 回答日時:
・コメント文がない
演習問題といえども、日頃からコメントを付加する習慣を
つけたほうがいいですよ。
人の書いたプログラムなんて初見では意味不明です。
・インデントがない
プログラムが非常に見づらく感じます。
あと、問題の原因は
putline関数の中でline配列に新たに文字列を入力している為です。
確認ですけど、getline関数が文字列を入力し、
putline関数が文字列を出力する関数ですよね?
ならputline関数の中でgetcharしなくてもいいはずです。
No.6
- 回答日時:
老婆心ながら一つ忠告しておきますが
「なんとなく」や「イメージ」ではプログラムは作れません。
ちゃんと関数の機能やアルゴリズム、仕様を理解して作ってください。
たとえ”まぐれ”で上手くいったとしても、
中身の分からないプログラムは無価値です。
とりあえず、どこがどのように分からないのか
示していただかないと、答えようがありません。
もうちょっと情報ください。
参考URL:http://www.bohyoh.com/CandCPP/C/Library/hindex.h …
この回答への補足
確実に理解していくように努めます。
関数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;
}
結果うまくいったようです。シンプルにまとめることができたと思うのですが、もっと明確にすべきところはありますでしょうか?
No.5
- 回答日時:
#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」しか浮びませんでした。
違いますよね^^; もう少しご教授頂けますか?
No.4
- 回答日時:
putline()で、出力すべきデータは配列tに入っています。
tから1文字ずつ取り出し、putchar()してください。
1文字ずつ取り出すのが終わるのは、'\0'が見つかったときです。
No.3
- 回答日時:
> ・インデントがない
> プログラムが非常に見づらく感じます。
仮に、元のソースがタブやスペースできちんとインデントしていたとしても、
アップロードした時点できれいさっぱり消えてしまいます。残念なことですけれど。
例えば全角スペースを使えば、アップロード結果はインデントしているように見えますが、
そうするとそのままコピー&ペーストしたのではコンパイルできない、
という痛しかゆしの状態です。
asuncionさんの仰る通りです^^; コピーペーストの結果、かなり見にくくなってしまったのに気付かなくて…すいませんでした。
初めての投稿だったもので、コメント文がないなど、気が付かなくてこれもまたすいませんでした。これから気をつけたいと思ってます。
putline内にgetcharは必要ないとのことでしたが、どのようにputcharを用いたらよろしいんでしょうか? 初心者で本当にお手数おかけします^^;;;
No.1
- 回答日時:
putline関数の機能(役割分担)は何でしょうか?
getline関数で入力を受け持っている上に、
さらにputline関数で入力を行なう必要はあるのでしょうか?
putline関数は、引数で受け取った内容を出力する、
という機能に特化すべきではないでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
nullと""、\\0とEOFの違いにつ...
-
[C++]WCHARの1文字目しか表示で...
-
C#でstringをポインタとして渡す
-
プログラムによく出てくるst...
-
[C#.net]正規表現による指定文...
-
WSH(VBS)でJSONの文字列を読み...
-
ソースコードの間違い (C言語)
-
C++で入力した文字列から数字を...
-
ASPで別サイトの内容を Stream ...
-
c#で他のアプリの文字入力フォ...
-
セグメントエラー
-
関数から配列を返すには?
-
VBAのプログラムで、DIAG = 1# ...
-
ExcelVBAで質問です。離れた二...
-
配列を使わずに、変数名を動的...
-
VC++6.0 MFC ダイアログバーを...
-
Integer変数をカラにしたいので...
-
先頭アドレスとは何ですか?
-
Run-Time Check Failure #3とい...
-
C言語で特定列だけを抽出して配...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C++で入力した文字列から数字を...
-
nullと""、\\0とEOFの違いにつ...
-
プログラムによく出てくるst...
-
%dなどの違い
-
WSH(VBS)でJSONの文字列を読み...
-
TCL言語で文字列検索方法を教え...
-
C#でstringをポインタとして渡す
-
16進数を2文字ずつ配列に格納し...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C++で文字列の右端から特定の文...
-
シリアル通信で0x00を送信した...
-
VBA-DLLの引数受け渡しについて
-
数字の入った配列をファイルへ...
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
Shift_JIS(16進)を文字に変換す...
-
バイナリファイル中の日本語文...
-
C言語の課題で困っています;
-
[C++]WCHARの1文字目しか表示で...
-
VB6.0でのバイナリデータの扱い...
おすすめ情報