- ベストアンサー
最も文字数が多い行番号と文字数を求めて出力するプログラム
タイトルの通りです。 何から始めていいのかわからないんでヒント教えてほしいです。 よろしくおねがいします。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
以下のサンプルは、string.hを使わない方法です。 でも、本当は、文字列の長さは、strlen関数使うと簡単なのは覚えておいてください。 最大文字数と最小文字数の両方をチェックします。 ※このプログラムの制限事項 (1)1行の長さはNULLを含めて最大128バイト (2)同じ長さの行が複数あっても一番最初の行が答えとなる。 FILE *stream; char szLine[128]; int nMaxLen = 0; // 最大文字数 int nMaxLineNo = 0; // 最大文字数の行番号 int nMinLen = 0; // 最小文字数 int nMinLineNo = 0; // 最小文字数の行番号 if( (stream = fopen( "C:\\sample.txt", "r" )) != NULL ) { // ファイルオープン成功 for (int nLineNo = 1; ; nLineNo++) { if( fgets( szLine, sizeof(szLine), stream ) == NULL) { // エラーあるいはファイルの終わりに達したのでループを抜ける break; } else { // strlenが使えないので自分で文字列の長さを調べる for (int nLength = 0; nLength < sizeof(szLine); nLength++) { if (szLine[nLength] == '\n') { // 行の最終に達したのでループを抜ける break; } } if (nLineNo == 1) { // ファイルの1行目の時 // ファイルの1行目の文字数と行番号は強制的に最小値としておく nMinLen = nLength; nMinLineNo = nLineNo; } // 最大文字数チェック if (nMaxLen < nLength) { // 今回readした行は今までで一番長いのでこれを最大値とする nMaxLen = nLength; // この時の行番号を最大文字数の時の行番号として覚えておく nMaxLineNo = nLineNo; } // 最小文字数チェック if (nMinLen > nLength) { // 今回readした行は今までで一番短いのでこれを最小値とする nMinLen = nLength; // この時の行番号を最小文字数の時の行番号として覚えておく nMinLineNo = nLineNo; } } } fclose( stream ); } printf("最大文字数=%d文字(%d行目)、最小文字数=%d文字(%d行目)\n", nMaxLen, nMaxLineNo, nMinLen, nMinLineNo);
その他の回答 (6)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>#include <string.h>をまだ習ってないんですが、これなしで作ることは可能でしょうか。 string.h は strlen(文字列の長さを求める関数) を使うために使っていますが、もちろん自分で作ることができます。 Cでの文字列は、最後に'\0'があるという約束があるので、'\0'がでてくるまで数えれば良いです。 #3では、fgetsを使って、一行入力をしていますが、 用意しているバッファを超えているときに一行を#3のプログラムではうまく扱えません。 むしろ、ファイルから1文字ずつ読み込んで'\n'が現れるまでの文字列を数えて'\n'が現れたら行の終わりとして計数したほうがいいかもしれません。 そうすると、必然的にstrlenは使わなくてすみます。
お礼
fgetsを使うプログラムも作ってみますね。 ありがとうございました。
- ID-PeaceC
- ベストアンサー率46% (97/209)
No.4です。 ファイルの1行目の文字数を強制的に最小値としてますが、同時に、最大値ともしておいた方がいいですね。 そうしないと途中で0文字の行があるとおかしなことになります。
お礼
なるほど^^ ありがとうございました。
- ID-PeaceC
- ベストアンサー率46% (97/209)
No.4です。 No.4のサンプルソースは、C++書式です。 もし、Cを勉強されてるなら、for文の中で直接宣言している int nLineNo とかは、関数の先頭に移動してください。 for (int nLineNo = 0・・・・ ↓ int nLineNo;(関数の先頭で) (中略) for (nLineNo = 0・・・・
お礼
#include<stdio.h> int main(void) { int c; int Line=0, wd=0; int small=128,big=0; int maxline=0,maxword=0; int minword=0,minline=0; while((c=getchar())!=EOF){ wd++; if(c=='\n'){ Line++;/* 一行読み込んだ */ if(wd>big){/*改行前までの数が、今までのbigより大きければ*/ big=wd; maxline=Line; } if(wd<small){/*改行前までの数が、今までのsmallより小さければ*/ small=wd; minline=Line; } wd=0;/*改行が終ったあと、一度0に初期化*/ } } printf("行番号 %d で、文字数 %d が最高!\n",maxline, big); printf("行番号 %d で、文字数 %d が最低!\n",minline, small); return(0); } こういうプログラムになりました^^; ありがとうございました^^
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
標準入力からテキストを入力して最も文字数が多い行番号と文字数を求める 一行が128より長い様な場合。 改行コードは数えるか? については、自分で考えてください。 #include <stdio.h> #include <string.h> #define BUFFSIZE 128 void main(void){ char buff[BUFFSIZE]; int line=0, len; int maxLine=0,maxChars=0; while(NULL!=fgets(buff,BUFFSIZE,stdin)){ line++;/* 一行読み込んだ */ len=strlen(buff); /* 文字数を数える */ if(maxChars<len){ /* 今の行が最高値を更新 */ maxChars=len; maxLine=line; } } printf("行番号 %d で、文字数 %d が最高!\n",maxLine, maxChars); }
お礼
#include <string.h>をまだ習ってないんですが、これなしで作ることは可能でしょうか。 最小値も求めないといけない課題なんで自力で頑張ってみます ありがとうございました。
- ID-PeaceC
- ベストアンサー率46% (97/209)
この方法がわからないということは、プログラミングは全く未経験でしょうか? (1)ファイルの長さ格納用変数を0初期化で宣言。 (2)ファイル開く (3)forループの中でファイルの最後まで一行単位でReadする。 (4)readする時、readしたバッファの長さを調べる。 ファイルの長さ格納用変数と長さを比較して、 今readしたバッファの長さの方が長いなら、 ファイルの長さ格納用変数にそれを代入する。 同時にその時のfor文のカウンタ値を退避しておく。 以上で、forループから抜けた時の、ファイルの長さ格納用変数の値と、退避しておいたfor文カウンタの値があなたの求めるものです。
お礼
勉強始めて一カ月です^^; 「ファイルの長さ格納用変数と長さを比較して、今readしたバッファの長さの方が長いなら、ファイルの長さ格納用変数にそれを代入する。」ってのがよくわからないんでもう少し考えてみます。 ありがとうございました。
- ngsvx
- ベストアンサー率49% (157/315)
まずは、各行の文字数を全部出力するプログラムを作ることからはじめてください。
お礼
頑張ってみます。 ありがとうございました。
お礼
実はNULLもまだ習ってないんでその部分もよくわかりません^^; 他の部分は参考にさせてもらいますね^^ 助かりました。ありがとうございました。
補足
あとstreamも習ってませんでした^^; なんとか頑張ってみます^^