ソースコードの行数
ソースコードの行数
初めまして。miiと申します。
課題でc言語のみを扱うステップ数をカウントするプログラムを作成するのですが、
良い方法が思いつかず困っています。
環境はborland C 5.5でWinVistaになります。
総ステップと実行ステップを求めるというもので、、
実行ステップを求める際にどうすればよいのか教えて頂きたいです。
実行ステップについてはコメント行と空白行を除いた行数となり
1 : /*コメント*/ printf("hello")
2 : printf("hello")
3 : // printf("hello")
なら実行ステップは1行目と2行目になるような仕様です。
総ステップ数と空白行の部分は何とかなりそうなのですが、
コメントの部分で/**/の処理をどうすればよいか分からないので、
具体的な考え方を教えて頂ければと思います。
よろしくお願いします。
課題でc言語のみを扱うステップ数をカウントするプログラムを作成するのですが、
良い方法が思いつかず困っています。
環境はborland C 5.5でWinVistaになります。
総ステップと実行ステップを求めるというもので、、
実行ステップを求める際にどうすればよいのか教えて頂きたいです。
実行ステップについてはコメント行と空白行を除いた行数となり
1 : /*コメント*/ printf("hello")
2 : printf("hello")
3 : // printf("hello")
なら実行ステップは1行目と2行目になるような仕様です。
総ステップ数と空白行の部分は何とかなりそうなのですが、
コメントの部分で/**/の処理をどうすればよいか分からないので、
具体的な考え方を教えて頂ければと思います。
よろしくお願いします。
Re:ソースコードの行数
一番簡単な方法としてはfgetcを使ったプログラムでしょうか。
一文字ずつ取ってきて、単純に改行コードが来た数だけカウントしてやれば
行数が解ると思います。
新しい行において、何か文字が来る前に改行コードが来たら空白行だとわかるでしょう。
また、/**/についてはフラグを用意したらいいのではないでしょうか。
/*が来たら「カウントしないフラグ」を立て、改行コードが来てもステップ数をカウントしないようにします。
*/が来たら「カウントしないフラグ」をおろし、改行コードが来たらステップ数をカウントするようにします。
これで出来るのではないでしょうか?
一文字ずつ取ってきて、単純に改行コードが来た数だけカウントしてやれば
行数が解ると思います。
新しい行において、何か文字が来る前に改行コードが来たら空白行だとわかるでしょう。
また、/**/についてはフラグを用意したらいいのではないでしょうか。
/*が来たら「カウントしないフラグ」を立て、改行コードが来てもステップ数をカウントしないようにします。
*/が来たら「カウントしないフラグ」をおろし、改行コードが来たらステップ数をカウントするようにします。
これで出来るのではないでしょうか?
Re:ソースコードの行数
初めまして。
学校の課題の場合、どの辺まで学んで、何を使って良いかが問題になります。すなわち、先生が
その課題で、何を学ばせようとしているかがあるはずです。
わかりやすくいえば、ファイルの入出力をどうするのか、ポインタは学んだのかなどです。
また、あなたがどれくらい習得しているかも知りたいところです。
>総ステップ数と空白行の部分は何とかなりそうなのですが
ということですので、総ステップ数(行数だとおもうけど)を求めるプログラムを
作って、添付してください。
学校の課題の場合、どの辺まで学んで、何を使って良いかが問題になります。すなわち、先生が
その課題で、何を学ばせようとしているかがあるはずです。
わかりやすくいえば、ファイルの入出力をどうするのか、ポインタは学んだのかなどです。
また、あなたがどれくらい習得しているかも知りたいところです。
>総ステップ数と空白行の部分は何とかなりそうなのですが
ということですので、総ステップ数(行数だとおもうけど)を求めるプログラムを
作って、添付してください。
Re:ソースコードの行数
おはようございます。
とりあえず総ステップ数を求めてみました。
ポインタ、ファイル等までは学習しています。
とりあえず総ステップ数を求めてみました。
ポインタ、ファイル等までは学習しています。
#include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp; // ファイルポインタ int lineCnt; // 行数 int blankLines; // 空白行 int c; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } lineCnt = 1; // 総ステップ数と空白行を求める while((c = fgetc(fp)) != EOF) { // 改行文字の場合行数を増やす if (c == '\n') { lineCnt++; } } printf("総ステップ数 = %d", lineCnt); return 0; }
Re:ソースコードの行数
問題の確認ですが、
1 空白行とは、TABも含みますよね。
2 最終行は、EOFのみの行でしょうか?それとも、文字があって行の終わりにEOFでしょうか?
または、どちらでも正しく計数する必要があるのでしょうか?
1 空白行とは、TABも含みますよね。
2 最終行は、EOFのみの行でしょうか?それとも、文字があって行の終わりにEOFでしょうか?
または、どちらでも正しく計数する必要があるのでしょうか?
Re:ソースコードの行数
最初に、空白行(TABを含む)をカウントするプログラムのみ作りましょう。
考え方としてはDixqさんが仰るようにフラグを使います。
まず、フラグの宣言です。
int space_flag=0;
カウントをクリアしておきましょう
blankLines=0;
スペースやTAB以外の文字が出てきたら、space_flag=1;にします。
改行文字のときに、space_flag==0のままならblankLinesをカウントアップします。
space_flag=0;に戻します。
ただし、プログラムするときは、
改行文字かチェックして、それ以外の場合に、空白文字以外かとチェックした方が簡単です。
そこまで、作ってみてください。
なお、EOFの場合分けは不明なので、まだ考えていません。
考え方としてはDixqさんが仰るようにフラグを使います。
まず、フラグの宣言です。
int space_flag=0;
カウントをクリアしておきましょう
blankLines=0;
スペースやTAB以外の文字が出てきたら、space_flag=1;にします。
改行文字のときに、space_flag==0のままならblankLinesをカウントアップします。
space_flag=0;に戻します。
ただし、プログラムするときは、
改行文字かチェックして、それ以外の場合に、空白文字以外かとチェックした方が簡単です。
そこまで、作ってみてください。
なお、EOFの場合分けは不明なので、まだ考えていません。
Re:ソースコードの行数
nonさんお世話になってます。
取りあえず作ってみました。
取りあえず作ってみました。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int lineCnt; // 行数 int blankLines = 0; // 空白行 int space_flag = 0; int ch; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } lineCnt = 1; // 総ステップ数と空白行を求める while((ch = fgetc(fp)) != EOF) { // 改行文字の場合行数を増やす if (ch =='\n') { lineCnt++; // 改行の後が空白だけなら if (space_flag == 0) { blankLines++; } space_flag = 0; } // 空白文字以外なら else if (!isspace(ch)) { space_flag = 1; } } printf("総ステップ数 = %d", lineCnt); printf("総空白数 = %d", blankLines); return 0; }
Re:ソースコードの行数
おぉ、もう出来そうじゃないですか。
後は私が上で言ったようにコメント部無視すれば完成ですね。
ヒント:
今読み取った文字が*で、一つ前に読み取った文字が/ならコメント開始ですね。終了はその逆。一つ前に読み取った文字は、新しい変数を一つ用意してループの最後に記憶させてやればOKです。
後は私が上で言ったようにコメント部無視すれば完成ですね。
ヒント:
今読み取った文字が*で、一つ前に読み取った文字が/ならコメント開始ですね。終了はその逆。一つ前に読み取った文字は、新しい変数を一つ用意してループの最後に記憶させてやればOKです。
Re:ソースコードの行数
さて、コメントはやっかいですね。
私が思いつく方法は3通り。
方法1 Dixqさんの方法。 1文字ずつ、処理していく。力業 。
方法2 配列(または動的に確保したメモリ)に1行分格納し、1行ずつ処理していく。
方法3 コメントを削除したファイルを中間ファイルとして保存し、再度読み込み、行数を数える。
一番簡単なのは方法3、一番ややこしいのが方法1です。どうします?
私が思いつく方法は3通り。
方法1 Dixqさんの方法。 1文字ずつ、処理していく。力業 。
方法2 配列(または動的に確保したメモリ)に1行分格納し、1行ずつ処理していく。
方法3 コメントを削除したファイルを中間ファイルとして保存し、再度読み込み、行数を数える。
一番簡単なのは方法3、一番ややこしいのが方法1です。どうします?
Re:ソースコードの行数
管理人さんお世話になります。
一応書いてみたのですが、グチャグチャでわからなくなってしまいました(汗
/* ~ */の間をコメント、そうでなければなどと考えていたら困ってきました。
どんな感じにすればよいでしょうか?
一応書いてみたのですが、グチャグチャでわからなくなってしまいました(汗
/* ~ */の間をコメント、そうでなければなどと考えていたら困ってきました。
どんな感じにすればよいでしょうか?
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int lineCnt; // 行数 int blankLines = 0; // 空白行 int space_flag = 0; int comentLines = 0; int cntOff = 0; int ch; int back; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } lineCnt = 1; // 総ステップ数と空白行を求める while((ch = fgetc(fp)) != EOF) { // 改行文字の場合行数を増やす if (ch =='\n' && cntOff != 1) { lineCnt++; // 改行の後が空白だけなら if (space_flag == 0) { blankLines++; } space_flag = 0; } // コメントの処理 else if (ch == '*') { // 前の文字が/なら if (back == '/') { cntOff = 1; } } // コメント終了 else if (ch == '/') { if (back == '*') { cntOff = 0; } } // 空白文字以外なら else if (!isspace(ch)) { space_flag = 1; } back = ch; } printf("総ステップ数 = %d\n", lineCnt); printf("総空白数 = %d\n", blankLines); printf("コメント行数 = %d\n", comentLines); /*kkk*/ printf("ss"); return 0; }
Re:ソースコードの行数
方法1の力業にしましたか。面倒だな・・・・。
とりあえず、方法3で作って、考え方を整理してから方法1を考えた方がいいと思います。
いきなり、方法1で作るなら、私はパス。
とりあえず、方法3で作って、考え方を整理してから方法1を考えた方がいいと思います。
いきなり、方法1で作るなら、私はパス。
Re:ソースコードの行数
いきなり力業にしましたが、確かにフラグ等も多くてわかりにくくなってしまいました。
とりあえず方法3でやってみたいと思うのですが、教えて頂けますでしょうか?
ちなみに処理ステップ数というのが追加されまして、
実行ステップ数のうち(プリプロセス行・中カッコのみの行を除いたステップ数)
という3種類を求めなければならない仕様になりました(泣
とりあえず方法3でやってみたいと思うのですが、教えて頂けますでしょうか?
ちなみに処理ステップ数というのが追加されまして、
実行ステップ数のうち(プリプロセス行・中カッコのみの行を除いたステップ数)
という3種類を求めなければならない仕様になりました(泣
Re:ソースコードの行数
方法3ならお手伝いしましょう。
まず、仕様をはっきりしましょう。
コメントには次のような場合があると思われます。
または、その複合です。
コメントのネストは面倒だから考えない。
ダブルコーテーションの間にあるコメントも面倒だから考えない。
という条件にしたいのですが。
これで、もれがないでしょうか?
それから追加された仕様ですが
>実行ステップ数のうち(プリプロセス行・中カッコのみの行を除いたステップ数)
意味がよくわかりません。{や}だけの行を除けということでしょうか?
PS
普通の授業の課題にしては結構面倒な課題ですね。
まさかとおもうけど、このあと、コンパイラを作ろうという話じゃないでしょうね。
まず、仕様をはっきりしましょう。
コメントには次のような場合があると思われます。
または、その複合です。
/* abc */ a=5;/* abc */ /* abc */ a=5; /* abc def ghi */ // abc a=5; // abcさらに、
コメントのネストは面倒だから考えない。
ダブルコーテーションの間にあるコメントも面倒だから考えない。
という条件にしたいのですが。
これで、もれがないでしょうか?
それから追加された仕様ですが
>実行ステップ数のうち(プリプロセス行・中カッコのみの行を除いたステップ数)
意味がよくわかりません。{や}だけの行を除けということでしょうか?
PS
普通の授業の課題にしては結構面倒な課題ですね。
まさかとおもうけど、このあと、コンパイラを作ろうという話じゃないでしょうね。
Re:ソースコードの行数
最終的には総ステップ数、実行ステップ数、処理ステップ数
を3つにわけて算出したいのですが、
a=5;/* abc */
a=5; // abc
/* abc */ a=5;
例えば上記のようなコメントは総ステップと実行ステップと処理ステップにカウントすればOKです!
// abc
/* abc */
/*
ab
*/
上記ならば総ステップ数だけカウントされればOKです!
} //abc
上記ならば総ステップと実行ステップにカウントされればOKです!
1.総ステップ数 (すべての行数)
2.実行ステップ数 (コメント行および空白行を除いた行数)
3.処理ステップ数 (実ステップ数のうち、プリプロセッサ行・
中カッコのみの行を除いたステップ数)
こんな感じです。
>さらに、コメントのネストは面倒だから考えない。
ダブルコーテーションの間にあるコメントも面倒だから考えない。という条件にしたいのですが。
これで、もれがないでしょうか?
大丈夫です!
>実行ステップ数のうち(プリプロセス行・中カッコのみの行を除いたステップ数)
意味がよくわかりません。{や}だけの行を除けということでしょうか?
これは実行ステップから先頭に#が付くもの(#ifや#include等です)と
中カッコは{や}だけというnonさんの見解で合ってます!
>PS 普通の授業の課題にしては結構面倒な課題ですね。
それはたぶん...ないと思います(笑
長くなってすみません。
を3つにわけて算出したいのですが、
a=5;/* abc */
a=5; // abc
/* abc */ a=5;
例えば上記のようなコメントは総ステップと実行ステップと処理ステップにカウントすればOKです!
// abc
/* abc */
/*
ab
*/
上記ならば総ステップ数だけカウントされればOKです!
} //abc
上記ならば総ステップと実行ステップにカウントされればOKです!
1.総ステップ数 (すべての行数)
2.実行ステップ数 (コメント行および空白行を除いた行数)
3.処理ステップ数 (実ステップ数のうち、プリプロセッサ行・
中カッコのみの行を除いたステップ数)
こんな感じです。
>さらに、コメントのネストは面倒だから考えない。
ダブルコーテーションの間にあるコメントも面倒だから考えない。という条件にしたいのですが。
これで、もれがないでしょうか?
大丈夫です!
>実行ステップ数のうち(プリプロセス行・中カッコのみの行を除いたステップ数)
意味がよくわかりません。{や}だけの行を除けということでしょうか?
これは実行ステップから先頭に#が付くもの(#ifや#include等です)と
中カッコは{や}だけというnonさんの見解で合ってます!
>PS 普通の授業の課題にしては結構面倒な課題ですね。
それはたぶん...ないと思います(笑
長くなってすみません。
Re:ソースコードの行数
まず、miiさんのプログラムから無駄なモノを省き、ファイルを読み込んで
1文字遅れで標準出力するプログラムにしました。
(最初の段階では、ファイルに出力せず、標準出力にしています)
理解できますでしょうか?
最初の1文字目を呼んだときは、1個前の文字がないため、出力しないように
変数startを使っています。
また、EOFにぶつかったとき最後の文字はまだ出力していないので、whileの外で
最後の文字を出力します。
するプログラムを作っていきます。
まずは、簡単なのは
// abc
a=5; // abc
のような//のコメントです。ここを最初に作りましょう。
今の文字chが'/'で1個前も'/'なら cntOff=1にします。
cntOff=1で1個前が改行なら cntOff=0 に戻します。
ここまで入力して、実行したら、//のコメントが消えれば正解です。
ここまで、できたら、プログラムを貼り付けてください。
1文字遅れで標準出力するプログラムにしました。
(最初の段階では、ファイルに出力せず、標準出力にしています)
理解できますでしょうか?
最初の1文字目を呼んだときは、1個前の文字がないため、出力しないように
変数startを使っています。
また、EOFにぶつかったとき最後の文字はまだ出力していないので、whileの外で
最後の文字を出力します。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int cntOff = 0; int ch; int back=0; int start=1; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { /* ここに処理を加えていく */ if(start==0 && cntOff==0) putchar(back); start=0; back = ch; } if(start==0 && cntOff==0) putchar(back); fclose(fp); return 0; }さて、ここで、コメントになれば、cntOffを0以外にして、コメントでない間はcntOff=0に
するプログラムを作っていきます。
まずは、簡単なのは
// abc
a=5; // abc
のような//のコメントです。ここを最初に作りましょう。
今の文字chが'/'で1個前も'/'なら cntOff=1にします。
cntOff=1で1個前が改行なら cntOff=0 に戻します。
ここまで入力して、実行したら、//のコメントが消えれば正解です。
ここまで、できたら、プログラムを貼り付けてください。
Re:ソースコードの行数
nonさんありがとうございます。
一応コメントが消えましたので貼ります。
一応コメントが消えましたので貼ります。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int cntOff = 0; int ch; int back=0; int start=1; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { /* ここに処理を加えていく */ if (ch == '/' && back == '/') { cntOff = 1; } if (cntOff == 1 && back == '\n') { cntOff = 0; } if(start==0 && cntOff==0) putchar(back); start=0; back = ch; } if(start==0 && cntOff==0) putchar(back); fclose(fp); return 0; }
Re:ソースコードの行数
では次に、/*~*/のコメントです。
基本的な考え方は//と同じです・
/*のとき cntOff = 2 にしましょう。
*/のとき cntOff=0 にすればよさそうですが、まだ*/の2文字を
出力したくないので、int count を用意して
cntOff=-1にしておいて、
count=2にします。
cntOff=-1のとき
count==0になったらcntOff=0にします。
そうでなければ、countを減らします。
ここまでで、コメントが消えると思いますが、コメントが複数行にわたったときは
改行は消したくありません。ですから、'\n'のときは、cntOffが何であってもputcharする
ように変更します。
じゃ、ここまで。
基本的な考え方は//と同じです・
/*のとき cntOff = 2 にしましょう。
*/のとき cntOff=0 にすればよさそうですが、まだ*/の2文字を
出力したくないので、int count を用意して
cntOff=-1にしておいて、
count=2にします。
cntOff=-1のとき
count==0になったらcntOff=0にします。
そうでなければ、countを減らします。
ここまでで、コメントが消えると思いますが、コメントが複数行にわたったときは
改行は消したくありません。ですから、'\n'のときは、cntOffが何であってもputcharする
ように変更します。
じゃ、ここまで。
Re:ソースコードの行数
この問題は、まともに考えると結構面倒ですね。
引用符やコメントのネストも本来は処理すべきですし、それ以外にも三文字表記や二文字表記も考慮しなければなりません。
//形式のコメントや前処理指令は、行末に\(または??/)がある場合には次の行に続くことになります。
前処理指令は、#のほか、??=や%:もあり得ます。
文字列リテラルの処理は、文字列中のエスケープとして、\以外に??/を考慮しなければなりません。
中かっこは、{と}の他に、<%と%>、または??<と??>を考慮しなければなりません。
引用符やコメントのネストも本来は処理すべきですし、それ以外にも三文字表記や二文字表記も考慮しなければなりません。
//形式のコメントや前処理指令は、行末に\(または??/)がある場合には次の行に続くことになります。
前処理指令は、#のほか、??=や%:もあり得ます。
文字列リテラルの処理は、文字列中のエスケープとして、\以外に??/を考慮しなければなりません。
中かっこは、{と}の他に、<%と%>、または??<と??>を考慮しなければなりません。
Re:ソースコードの行数
とりあえず出来たので張ります。
お忙しい中ありがとうございます!
ちょっとフラグの状態で戸惑ってしまいました(汗
お忙しい中ありがとうございます!
ちょっとフラグの状態で戸惑ってしまいました(汗
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int cntOff = 0; int ch; int back=0; int start=1; int count = 0; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch == '/' && back == '/') { cntOff = 1; } else if (ch == '*' && back == '/') { cntOff = 2; } else if (ch == '/' && back == '*') { cntOff = -1; count = 2; } if (cntOff == 1 && back == '\n') { cntOff = 0; } else if (cntOff == -1) { if (count == 0) { cntOff = 0; } else { count--; } } if(start==0 && cntOff==0) putchar(back); start=0; back = ch; } if(start==0 && cntOff==0) putchar(back); fclose(fp); return 0; }
Re:ソースコードの行数
>ここまでで、コメントが消えると思いますが、コメントが複数行にわたったときは
>改行は消したくありません。ですから、'\n'のときは、cntOffが何であってもputcharする
>ように変更します。
まだ、ここができてませんね。
a=10; /* bbbb
cccc */b=20;
のような場合、
このままでは、
a=10;b=20;
のように1行になってしまいませんか?
あとで、総行数をカウントしなければいけないのでまずいです。
ま、すぐにできるでしょうから、次に進みましょう。
では、次に、方法3なら
○中間ファイルを書き込みようにオープンする。
○putcharをputcに書き換える。
○一度クローズした後、先に作った行数をカウントするプログラムを後ろに貼り付ける。
でうまくいくはずです。
さて、しかし方法3の目途が立ったので、方法3をせずに、(してもいいけど)方法1に
変更します。
今作ったプログラムでputcharする文字が、ファイルから入力する文字だと考えればよいので、
このputcharの所に、前作ったプログラム(No43625)のwhileの中のプログラムをコピーします。
また、最後のputcharの所にも、必要なカウント部分を入れます。
最後のputcharの所のためには仕様をはっきりさせておく必要があります。
それは、EOFのみの行は1行として数えるのか否かです。
なお、後で追加された仕様は、自分で考えてみてください。
>改行は消したくありません。ですから、'\n'のときは、cntOffが何であってもputcharする
>ように変更します。
まだ、ここができてませんね。
a=10; /* bbbb
cccc */b=20;
のような場合、
このままでは、
a=10;b=20;
のように1行になってしまいませんか?
あとで、総行数をカウントしなければいけないのでまずいです。
ま、すぐにできるでしょうから、次に進みましょう。
では、次に、方法3なら
○中間ファイルを書き込みようにオープンする。
○putcharをputcに書き換える。
○一度クローズした後、先に作った行数をカウントするプログラムを後ろに貼り付ける。
でうまくいくはずです。
さて、しかし方法3の目途が立ったので、方法3をせずに、(してもいいけど)方法1に
変更します。
今作ったプログラムでputcharする文字が、ファイルから入力する文字だと考えればよいので、
このputcharの所に、前作ったプログラム(No43625)のwhileの中のプログラムをコピーします。
また、最後のputcharの所にも、必要なカウント部分を入れます。
最後のputcharの所のためには仕様をはっきりさせておく必要があります。
それは、EOFのみの行は1行として数えるのか否かです。
なお、後で追加された仕様は、自分で考えてみてください。
Re:ソースコードの行数
とりあえず方法3で作成したみたのですが、
実行ステップ数が10桁の数字になってしまいます(汗
どのようにすればよいでしょうか?
実行ステップ数が10桁の数字になってしまいます(汗
どのようにすればよいでしょうか?
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp, *wfp; int space_flag = 0; int cntOff = 0; int ch; int back=0; int start=1; int count = 0; int lineCnt; int blankLines; printf("a");/* ファイルオープン abc*/ printf("b"); if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } if ((wfp = fopen("out.c", "w")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch == '/' && back == '/') { cntOff = 1; } else if (ch == '*' && back == '/') { cntOff = 2; } else if (ch == '/' && back == '*') { cntOff = -1; count = 2; } if (cntOff == 1 && back == '\n') { cntOff = 0; } else if (cntOff == -1) { if (count == 0) { cntOff = 0; } else { count--; } } if (start == 0 && cntOff == 0) { putc(back, wfp); } else if (back == '\n') { putc(back, wfp); } start=0; back = ch; } if (start == 0 && cntOff == 0) { putc(back, wfp); } fclose(wfp); fclose(fp); if ((fp = fopen("out.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } lineCnt = 1; while((ch = fgetc(fp)) != EOF) { if (ch =='\n') { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; } else if (!isspace(ch)) { space_flag = 1; } } printf("総ステップ数 = %d\n", lineCnt); printf("実行ステップ数 = %d\n", blankLines); fclose(fp); return 0; }
Re:ソースコードの行数
すいません初期化に今気づきました。。。
っとnonさんの方が先でしたか(汗
すみませんでした。
ただやはり結果がおかしくて、実行ステップ数が合いません(泣
もう少し見てみます。
っとnonさんの方が先でしたか(汗
すみませんでした。
ただやはり結果がおかしくて、実行ステップ数が合いません(泣
もう少し見てみます。
Re:ソースコードの行数
if (start == 0 && cntOff == 0) { putc(back, wfp); } else if (back == '\n') { putc(back, wfp); }これでも間違ってはないけど、後で方法1にするときに、putcのところに
プログラムを挿入したいから、putcを1つにまとめましょう。
if ((start == 0 && cntOff == 0) || back == '\n') { putc(back, wfp); }このようにね。
Re:ソースコードの行数
なんとかいけました。
ありがとうございます。
ありがとうございます。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp, *wfp; // ファイルポインタ int cntOff = 0; // 0はコメントでない間 int ch; int back=0; int start=1; int count = 0; int lineCnt; int blankLines = 0; int space_flag = 0; printf("a");/* ファイルオープン abc*/ printf("b"); //int /*kokikjhj*/ if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } if ((wfp = fopen("out.c", "w")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch == '/' && back == '/') { cntOff = 1; } else if (ch == '*' && back == '/') { cntOff = 2; } else if (ch == '/' && back == '*') { cntOff = -1; count = 2; } if (cntOff == 1 && back == '\n') { cntOff = 0; } else if (cntOff == -1) { if (count == 0) { cntOff = 0; } else { count--; } } if ((start == 0 && cntOff == 0) || back == '\n') { putc(back, wfp); } start=0; back = ch; } if (start == 0 && cntOff == 0) { putc(back, wfp); } fclose(wfp); fclose(fp); if ((fp = fopen("out.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } lineCnt = 1; while((ch = fgetc(fp)) != EOF) { if (ch =='\n') { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; } else if (!isspace(ch)) { space_flag = 1; } } printf("総ステップ数 = %d\n", lineCnt); printf("実行ステップ数 = %d\n", lineCnt - blankLines); fclose(fp); return 0; }
Re:ソースコードの行数
おはようございます。
「うまくいかない」だけでは、原因は、わかりません。
whileはいらないですからね。whileの中だけね。
もちろん、chはbackに直してね。
「うまくいかない」だけでは、原因は、わかりません。
whileはいらないですからね。whileの中だけね。
もちろん、chはbackに直してね。
Re:ソースコードの行数
おはようございます。
とりあえず直してみました。
どこがダメなのでしょうか?
とりあえず直してみました。
どこがダメなのでしょうか?
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int cntOff = 0; // 0はコメントでない間 int ch; int back=0; int start=1; int count = 0; int lineCnt = 1; int blankLines = 0; int space_flag = 0; if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch == '/' && back == '/') { cntOff = 1; } else if (ch == '*' && back == '/') { cntOff = 2; } else if (ch == '/' && back == '*') { cntOff = -1; count = 2; } if (cntOff == 1 && back == '\n') { cntOff = 0; } else if (cntOff == -1) { if (count == 0) { cntOff = 0; } else { count--; } } if ((start == 0 && cntOff == 0) || back == '\n') { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; if (!isspace(back)) { space_flag = 1; } } start=0; back = ch; } if (start == 0 && cntOff == 0) { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; if (!isspace(back)) { space_flag = 1; } } fclose(fp); printf("総ステップ数 = %d\n", lineCnt); printf("実行ステップ数 = %d\n", lineCnt - blankLines); fclose(fp); return 0; }
Re:ソースコードの行数
No43666ではwhileの中身は下のようだけど、上は違うじゃん。
if (ch =='\n') { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; } else if (!isspace(ch)) { space_flag = 1; }
Re:ソースコードの行数
>No43666ではwhileの中身は下のようだけど、上は違うじゃん。
ただそうすると今度は総ステップも実行ステップも1になってしまいます(泣
ちなみに上記No43666のchをbackに直してみてもだめでした。
ただそうすると今度は総ステップも実行ステップも1になってしまいます(泣
ちなみに上記No43666のchをbackに直してみてもだめでした。
Re:ソースコードの行数
よろしくお願いします。
フラグの状態と変化を理解していないから、
わからないんだと思います(泣
う~ん混乱してきました。
フラグの状態と変化を理解していないから、
わからないんだと思います(泣
う~ん混乱してきました。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int cntOff = 0; // 0はコメントでない間 int ch; int back=0; int start=1; int count = 0; int lineCnt = 1; int blankLines = 0; int space_flag = 0; if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch == '/' && back == '/') { cntOff = 1; } else if (ch == '*' && back == '/') { cntOff = 2; } else if (ch == '/' && back == '*') { cntOff = -1; count = 2; } if (cntOff == 1 && back == '\n') { cntOff = 0; } else if (cntOff == -1) { if (count == 0) { cntOff = 0; } else { count--; } } if ((start == 0 && cntOff == 0) || back == '\n') { if (ch =='\n') { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; } else if (!isspace(ch)) { space_flag = 1; } start=0; back = ch; } } if (start == 0 && cntOff == 0) { if (ch =='\n') { lineCnt++; if (space_flag == 0) { blankLines++; } space_flag = 0; } else if (!isspace(ch)) { space_flag = 1; } } fclose(fp); printf("総ステップ数 = %d\n", lineCnt); printf("実行ステップ数 = %d\n", lineCnt - blankLines); fclose(fp); return 0; }
Re:ソースコードの行数
テストは少ししかしていませんがちゃんと動いています。
nonさんありがとうございます!
ただこれに追加分を付けるとなると。。。先が思いやられます(T_T)
nonさんありがとうございます!
ただこれに追加分を付けるとなると。。。先が思いやられます(T_T)
Re:ソースコードの行数
度々すみません。
先ほどテストしていたんですがバグがありました。
になってしまいました。どこがおかしいのでしょうか?
先ほどテストしていたんですがバグがありました。
#include <stdio.h> /*#include <stdlib.h>*/ #include <ctype.h> //int main(void) /* kome }*/ abc abc //komeというファイルでテストしていたのですが、期待する結果とは違う結果
になってしまいました。どこがおかしいのでしょうか?
Re:ソースコードの行数
何度もいうようですが、どのプログラムでどのように期待していたら、どう期待する結果と
違うのかがわからないと答えようがないです。
プログラムは添付ファイルのままですか?
違うのかがわからないと答えようがないです。
プログラムは添付ファイルのままですか?
Re:ソースコードの行数
おはようございます。
>何度もいうようですが、どのプログラムでどのように期待していたら、どう期待する結果と
違うのかがわからないと答えようがないです。
プログラムは添付ファイルのままですか?
その通りです。問題提示だけしてしまってすみませんでした。
プログラムムは添付のままで、以下がテストファイル内容です。
とりあえずコンパイルが通るという条件でテストファイルを作成しました。
実行ステップが12になってしまいます。よろしくお願いいたします。
>何度もいうようですが、どのプログラムでどのように期待していたら、どう期待する結果と
違うのかがわからないと答えようがないです。
プログラムは添付ファイルのままですか?
その通りです。問題提示だけしてしまってすみませんでした。
プログラムムは添付のままで、以下がテストファイル内容です。
とりあえずコンパイルが通るという条件でテストファイルを作成しました。
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int a; // a 6 7 // aだよ int b; 8 9 /* 10 int 11 int 12 */ int b; 13 14 /***************************************** 15 **********************/ 16 } 17 #include <stdio.h> 18 19 /*#include <stdlib.h>*/ 20 21 #include <ctype.h> 22 23 //int main(void) 24 25 26 27 /* 28 29 kome 30 31 }*/ double abc; 32 33 34 35 double cba; //kome 36 37 [EOF]上記だと総ステップが37、実行ステップが10になるようにしたいのですが、
実行ステップが12になってしまいます。よろしくお願いいたします。
Re:ソースコードの行数
whileから抜けた後の、putcharの代わりに挿入したプログラムに問題があります。
backに入っている文字は1文字前であることから、最後の1文字を考慮しなくてはいけません。
今回のようにEOFの1つ前の行が、空白行の時のカウントをするプログラム部分が必要ですが、
ここには書かれていません。
もう一つは、No:43654 の最後で書いたように、EOFしかない行を1行として数えるかどうかです。
もし、数えるのなら、このような場合は当然空白行としてもカウントが必要です。
なお、データに行番号がついていると、同じ条件で試せないので、不便です。
backに入っている文字は1文字前であることから、最後の1文字を考慮しなくてはいけません。
今回のようにEOFの1つ前の行が、空白行の時のカウントをするプログラム部分が必要ですが、
ここには書かれていません。
もう一つは、No:43654 の最後で書いたように、EOFしかない行を1行として数えるかどうかです。
もし、数えるのなら、このような場合は当然空白行としてもカウントが必要です。
なお、データに行番号がついていると、同じ条件で試せないので、不便です。
Re:ソースコードの行数
>なお、データに行番号がついていると、同じ条件で試せないので、不便です。
わざわざつけちゃってすいません。逆に不便ですよね。消したものを張りなおします!
これはどういう風に書いたらよいでしょうか?
わざわざつけちゃってすいません。逆に不便ですよね。消したものを張りなおします!
// 最初の文字でないかつ非コメント状態であれば if (start == 0 && cntOff == 0) { if (back =='\n') { lineCnt++; } // この部分を追加しました // EOFしかない行を1行として数える if (space_flag == 0) { blankLines++; } }>今回のようにEOFの1つ前の行が、空白行の時のカウントをするプログラム部分が必要
これはどういう風に書いたらよいでしょうか?
Re:ソースコードの行数
#include <stdio.h>
int main(void)
{
int a; // a
// aだよ int b;
/*
int
int
*/ int b;
/*****************************************
**********************/
}
#include <stdio.h>
/*#include <stdlib.h>*/
#include <ctype.h>
総数は37になります!
//int main(void)
/*
kome
}*/ double abc;
double cba; //kome
int main(void)
{
int a; // a
// aだよ int b;
/*
int
int
*/ int b;
/*****************************************
**********************/
}
#include <stdio.h>
/*#include <stdlib.h>*/
#include <ctype.h>
総数は37になります!
//int main(void)
/*
kome
}*/ double abc;
double cba; //kome
Re:ソースコードの行数
whileの外の部分はこんな感じかな?チェックをあまりしてないけど。
if (start == 0) { if (back =='\n') { lineCnt++; blankLines++; } if (space_flag == 0) blankLines++; } else{ blankLines=1; }
Re:ソースコードの行数
ありがとうございます!
whileの外部分をnonさんのソースでためした所希望通りの結果が出ました。
ちなみに3番目の仕様については#がきたらその行をカウント、
カッコだけがきたらその行をカウントする方法でよいでしょうか?
ただカッコだけとなるとどう判断すればいいのか困っています。
whileの外部分をnonさんのソースでためした所希望通りの結果が出ました。
ちなみに3番目の仕様については#がきたらその行をカウント、
カッコだけがきたらその行をカウントする方法でよいでしょうか?
ただカッコだけとなるとどう判断すればいいのか困っています。
Re:ソースコードの行数
とりあえず関数化してコメントを付けて見ました。
処理ステップ数 (実ステップ数のうち、プリプロセッサ行・中カッコのみの行を除いたステップ数)
を求める為にはどうすればよいでしょうか?
よろしくお願いします。
処理ステップ数 (実ステップ数のうち、プリプロセッサ行・中カッコのみの行を除いたステップ数)
を求める為にはどうすればよいでしょうか?
よろしくお願いします。
Re:ソースコードの行数
後は自分で考えて欲しいのだけど・・・
じゃ、最後のヒントで。
まず、仕様の条件を絞ること。
今回は#が出てきた行数と{または}のみ現れた行数をカウントしました。
じゃ、最後のヒントで。
まず、仕様の条件を絞ること。
今回は#が出てきた行数と{または}のみ現れた行数をカウントしました。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int lineCnt; // 行数 int sharpLines = 0; // 空白行 int sharp_flag = 0; int braceLines = 0; int brace_flag =0; int ch; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch =='\n') { if (sharp_flag == 1) sharpLines++; if (brace_flag ==1) braceLines++; sharp_flag = 0; } else if (!isspace(ch)){ if (ch == '{' || ch == '}') if(brace_flag==0) brace_flag=1; else brace_flag=2; } if (ch=='#') { sharp_flag = 1; } } printf("プリプロセッサ = %d\n", sharpLines); printf("括弧の行 = %d\n", braceLines); return 0; }
Re:ソースコードの行数
本当にありがとうございます!
実行してみたんですが
#include
int main(void) {
}
}
}
{
とすると括弧の数が4になって欲しいのですが2と表示されてしまいます。
どうしたらよいでしょうか?
実行してみたんですが
#include
int main(void) {
}
}
}
{
とすると括弧の数が4になって欲しいのですが2と表示されてしまいます。
どうしたらよいでしょうか?
Re:ソースコードの行数
テストしてなかったので、抜けがありましたね。
今度は実行して確認しました。
今度は実行して確認しました。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int lineCnt; // 行数 int sharpLines = 0; // 空白行 int sharp_flag = 0; int braceLines = 0; int brace_flag =0; int ch; // ファイルオープン if ((fp = fopen("a.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while((ch = fgetc(fp)) != EOF) { if (ch =='\n') { if (sharp_flag == 1) sharpLines++; if (brace_flag ==1) braceLines++; sharp_flag = 0; brace_flag=0; } else if (!isspace(ch)){ if (ch == '{' || ch == '}'){ if(brace_flag==0) brace_flag=1; } else brace_flag=2; } if (ch=='#') { sharp_flag = 1; } } printf("プリプロセッサ = %d\n", sharpLines); printf("括弧の行 = %d\n", braceLines); return 0; }
Re:ソースコードの行数
う~ん。。。やはり中々上手くいきませんね(泣
nonさんに頂いたサンプルだと上手く動くのですが、
組み込んでみたら上手くカウント出来ませんでした。
なぜか括弧の数が少なく出てきます。。。
何度もすいません。
nonさんに頂いたサンプルだと上手く動くのですが、
組み込んでみたら上手くカウント出来ませんでした。
なぜか括弧の数が少なく出てきます。。。
何度もすいません。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(void) { FILE *fp; // ファイルポインタ int currentChar; // 現在の文字 int backChar = 0; // 1個前の文字 int commentFlag = 0; // 各コメント状態を表す int countFlag = 0; // 複数行コメントの終了判定 int spaceFlag = 0; // 空白又はTABを判定 int startFlag = 1; // 最初の文字か判定 int lineCnt = 0; // 総ステップ数 int nonRealCnt = 0; // 実ステップ数に含めない数 int sharp_flag = 0; int brace_flag = 0; int sharpLines = 0; int braceLines = 0; // ファイルオープン if ((fp = fopen("b.c", "r")) == NULL) { printf("open error\n"); exit(EXIT_FAILURE); } while ((currentChar = fgetc(fp)) != EOF) { // 単一行コメントの開始 if (currentChar == '/' && backChar == '/') { commentFlag = 1; } // 複数行コメントの開始 else if (currentChar == '*' && backChar == '/') { commentFlag = 2; } // 複数行コメントの継続 else if (currentChar == '/' && backChar == '*') { commentFlag = -1; countFlag = 2; } // 単一行コメント終了判断 if (commentFlag == 1 && backChar == '\n') { commentFlag = 0; } // 複数行コメント終了判断 else if (commentFlag == -1) { // 複数行コメントが非コメント状態 if (countFlag == 0) { commentFlag = 0; } // 複数行コメント継続状態 else { countFlag--; } } // 非コメント状態又は読み取った文字の1個前が改行文字のいずれか if ((startFlag == 0 && commentFlag == 0) || backChar == '\n') { // 1個前の文字が改行文字だった場合 if (backChar =='\n') { lineCnt++; if (sharp_flag == 1) { sharpLines++; } if (brace_flag == 1) { braceLines++; } // コメント又は空白行であれば if (spaceFlag == 0) { nonRealCnt++; } spaceFlag = 0; sharp_flag = 0; brace_flag = 0; } // 1個前の文字が空白又はTAB文字文字以外の場合 else if (!isspace(backChar)) { if (backChar == '{' || backChar == '}') { if (brace_flag == 0) { brace_flag = 1; } } spaceFlag = 1; } else { brace_flag = 2; } if (backChar == '#') { sharp_flag = 1; } } startFlag = 0; backChar = currentChar; } printf("プリプロセッサ = %d\n", sharpLines); printf("括弧の行 = %d\n", braceLines); return 0; }
Re:ソースコードの行数
nonさんありがとうございます。
以下のテスト用ファイルを用いてテストを行っているのですが
総ステップ27
実行ステップ18
処理ステップ11
となり実行ステップ17、処理ステップ10となる予定でした。
どこがおかしいのでしょうか?
ちなみにEOFのみの場合は行に含めず、1文字以上の何か文字や、
空白があった場合は行数にカウントするということになりました(泣
これは0からカウントすることで何とかしているんですが、
EOF行だけの場合、文字が来たときに1行とするのはどうすればよいでしょうか?
質問ばかりですみません。
以下のテスト用ファイルを用いてテストを行っているのですが
総ステップ27
実行ステップ18
処理ステップ11
となり実行ステップ17、処理ステップ10となる予定でした。
どこがおかしいのでしょうか?
ちなみにEOFのみの場合は行に含めず、1文字以上の何か文字や、
空白があった場合は行数にカウントするということになりました(泣
これは0からカウントすることで何とかしているんですが、
EOF行だけの場合、文字が来たときに1行とするのはどうすればよいでしょうか?
質問ばかりですみません。
Re:ソースコードの行数
>ちなみにEOFのみの場合は行に含めず、1文字以上の何か文字や、
空白があった場合は行数にカウントするということに
これはどういう風に修正すればよいでしょうか?
どうしても修正すると他の部分に影響が出たりして上手くいきません(泣
空白があった場合は行数にカウントするということに
これはどういう風に修正すればよいでしょうか?
どうしても修正すると他の部分に影響が出たりして上手くいきません(泣
Re:ソースコードの行数
最終行は、EOFのみの行でも、文字があって行の終わりにEOFでも正しく計算するには、
大幅な修正が必要なんでしょうか?どうすれば良いでしょうか(T_T)
大幅な修正が必要なんでしょうか?どうすれば良いでしょうか(T_T)
Re:ソースコードの行数
かなり手こずっておられますね・・・。
>最終行は、EOFのみの行でも、文字があって行の終わりにEOFでも正しく計算するには、
>大幅な修正が必要なんでしょうか?どうすれば良いでしょうか(T_T)
EOFがくるとwhile文を抜けますが、抜けた先でbackCharの値を見てフラグを更新した後、
フラグの状態を見て行数をカウントすれば良いのでは?
ただ、backCharを見て行数をカウントするよりcurrentCharを見て行数をカウントする方が
都合がいいような気がします。
(これまでの流れを全て追っているわけではないので見当違いかもしれませんが・・・)
それから、最終結果が自分の想定した結果と違うということを言っておられますが
途中経過のどこで想定と食い違っているか把握していますか?
ファイルから読みとった文字を1文字ずつコンソール画面に表示していき、
改行文字またはEOFが来たら、その行が何の行と判定されたかを表示していけば
問題がある部分を把握しやすくなると思います。
>最終行は、EOFのみの行でも、文字があって行の終わりにEOFでも正しく計算するには、
>大幅な修正が必要なんでしょうか?どうすれば良いでしょうか(T_T)
EOFがくるとwhile文を抜けますが、抜けた先でbackCharの値を見てフラグを更新した後、
フラグの状態を見て行数をカウントすれば良いのでは?
ただ、backCharを見て行数をカウントするよりcurrentCharを見て行数をカウントする方が
都合がいいような気がします。
(これまでの流れを全て追っているわけではないので見当違いかもしれませんが・・・)
それから、最終結果が自分の想定した結果と違うということを言っておられますが
途中経過のどこで想定と食い違っているか把握していますか?
ファイルから読みとった文字を1文字ずつコンソール画面に表示していき、
改行文字またはEOFが来たら、その行が何の行と判定されたかを表示していけば
問題がある部分を把握しやすくなると思います。
Re:ソースコードの行数
おはようございます。
昨日レビューらしきものをしたんですが、//がきたら改行まで読み飛ばす。
/*がきたら*/を探してしまえばいいんじゃないかという風になってしまいました(汗
何やら混乱状態です(T_T)
>それから、最終結果が自分の想定した結果と違うということを言っておられますが
途中経過のどこで想定と食い違っているか把握していますか?
やはりここが問題です。フラグの制御を追い切れていないのが原因ですよね。
>ファイルから読みとった文字を1文字ずつコンソール画面に表示していき、
改行文字またはEOFが来たら、その行が何の行と判定されたかを表示していけば
問題がある部分を把握しやすくなると思います。
なるほど!ちょっとその方法で試してみます!
ありがとうございました。
昨日レビューらしきものをしたんですが、//がきたら改行まで読み飛ばす。
/*がきたら*/を探してしまえばいいんじゃないかという風になってしまいました(汗
何やら混乱状態です(T_T)
>それから、最終結果が自分の想定した結果と違うということを言っておられますが
途中経過のどこで想定と食い違っているか把握していますか?
やはりここが問題です。フラグの制御を追い切れていないのが原因ですよね。
>ファイルから読みとった文字を1文字ずつコンソール画面に表示していき、
改行文字またはEOFが来たら、その行が何の行と判定されたかを表示していけば
問題がある部分を把握しやすくなると思います。
なるほど!ちょっとその方法で試してみます!
ありがとうございました。
Re:ソースコードの行数
//がきたら改行まで読み飛ばす
/*がきたら次の*/まで読み飛ばすようにして、
コメント行、空白行を分けてカウントするようにしました。
1 int a; // コメント
2 /*
3 コメント
4 コメント
5 コメント
6 */ int a;
などと入力されていると、
1行目と6行目はコメント行に認識したくないのですが、
コメント行と認識されてしまいます。
どういう風に修正したらよいでしょうか?
/*がきたら次の*/まで読み飛ばすようにして、
コメント行、空白行を分けてカウントするようにしました。
1 int a; // コメント
2 /*
3 コメント
4 コメント
5 コメント
6 */ int a;
などと入力されていると、
1行目と6行目はコメント行に認識したくないのですが、
コメント行と認識されてしまいます。
どういう風に修正したらよいでしょうか?
Re:ソースコードの行数
まだやってたのねと思って覗いたら・・・
>昨日レビューらしきものをしたんですが、//がきたら改行まで読み飛ばす。
>/*がきたら*/を探してしまえばいいんじゃないかという風になってしまいました(汗
いつのまにかアルゴリズムが変わったのね。
「なってしまいました」ってのが、よくわからないけど。チームですか?
まっ、いずれにしても、私は厭きたので、頑張ってください。
アルゴリズムも変わったし、スレッドを立て直したら、他の方のレスもあるかもね。
>昨日レビューらしきものをしたんですが、//がきたら改行まで読み飛ばす。
>/*がきたら*/を探してしまえばいいんじゃないかという風になってしまいました(汗
いつのまにかアルゴリズムが変わったのね。
「なってしまいました」ってのが、よくわからないけど。チームですか?
まっ、いずれにしても、私は厭きたので、頑張ってください。
アルゴリズムも変わったし、スレッドを立て直したら、他の方のレスもあるかもね。
Re:ソースコードの行数
nonさんが厭きておられるようなので代わりに・・・
>1行目と6行目はコメント行に認識したくないのですが、
>コメント行と認識されてしまいます。
コメントを読み飛ばしている最中に'\n'が来たら、その行はコメント行として
カウントしていることが問題です。
混乱しているなら、まず問題を整理することからはじめましょう。
1行の中にどのような項目が存在する可能性があるか考えてください。
・空白類文字
・コメント
・中カッコ
・前処理
・その他の文字
の5つですね。
という事は'\n'またはEOFを読み込んだときに5種類のフラグの状態を調べて
何の行なのかを判定すればいいことになりませんか?
後はどのフラグが立っているときに何の行と判定すればいいのかを
見抜く事ができればとりあえず完成しそうです。
>1行目と6行目はコメント行に認識したくないのですが、
>コメント行と認識されてしまいます。
コメントを読み飛ばしている最中に'\n'が来たら、その行はコメント行として
カウントしていることが問題です。
混乱しているなら、まず問題を整理することからはじめましょう。
1行の中にどのような項目が存在する可能性があるか考えてください。
・空白類文字
・コメント
・中カッコ
・前処理
・その他の文字
の5つですね。
という事は'\n'またはEOFを読み込んだときに5種類のフラグの状態を調べて
何の行なのかを判定すればいいことになりませんか?
後はどのフラグが立っているときに何の行と判定すればいいのかを
見抜く事ができればとりあえず完成しそうです。
Re:ソースコードの行数
ドラさんありがとうございます。
そういう方法があったのですね!
思いつかず、力技で処理してしまいました。
論理的じゃないのできっとバグがあると思いますが(汗
後はEOF行だけの時の処理ですが、
これも力技しかないのかなぁと。
考えるのは難しいですね。。。(泣
そういう方法があったのですね!
思いつかず、力技で処理してしまいました。
論理的じゃないのできっとバグがあると思いますが(汗
後はEOF行だけの時の処理ですが、
これも力技しかないのかなぁと。
考えるのは難しいですね。。。(泣
Re:ソースコードの行数
取りあえず修正した後、
以下のテストファイルを用いてテストしてみました。
<test1>
/**/#include <stdio.h>#include <stdlib.h>/* --- */int a;
#define LOKI 123
#define IKOL 123
#
void main()
{ //ask
int a,b ;/* bbb */
a=0;/* ccc */ /*
a\n
a */
/* ddd */ /* ooo
a\n
a */
a=0 ;/* eee */ /* */ /* */
//aaa
b=a ;//
b=a ; /* b */b=b;
printf( "\" " ) ;
b=1 ;
while(a!=b)
{ a=b ;
}
// printf( "%d\n",LOKI ) ;
/*/
int g;
*/
}
正しくは
コメント行 = 10
空白行 = 0
シャープ行 = 4
中カッコ行 = 3
なのですが
コメント行が9
中カッコ行が2になってしまいます。
<test2>
/**/#include <stdio.h>#include <stdlib.h>/* --- */int a;
#define LOKI 123
#define IKOL 123
#
/**/#define AA 123/***/
//#define BB 456
#define CC 789 /*
#define DD 741
*/
void main()
{ //ask
int a,b ;/* bbb */
a=0;/* ccc */ /*
a\n
a */
/* ddd */ /* ooo
a\n
a */
a=0 ;/* eee */ /* */ /* */
//aaa
b=a ;//
b=a ; /* b */b=b;
printf( "\" " ) ;
b=1 ;
while(a!=b)
{ a=b ;
}
// printf( "%d\n",LOKI ) ;
/*/
int g;
*/
}
int main2()
{ int j;/*
*/ int i;/***//**//*
int bb;
*/
// int cc;
for (i = 9; i< 10; i++) {
/**/{/**/ printf("%d\n", i);
}} // aaaa
/**/}}
こちらは正しくは
コメント行 = 16
空白行 = 2
シャープ行 = 6
中カッコ行 = 5
なのですが
中カッコ行が2になってしまいます。
こちらはなぜかコメントは正常でした。
どこに問題があるか教えていただけないでしょうか?
またファイル内容がEOFのみの1行だけの場合
上手く処理出来ません(泣
最初の1文字を上手く取れてないんでしょうか?
お力添えよろしくお願いいたします。
以下のテストファイルを用いてテストしてみました。
<test1>
/**/#include <stdio.h>#include <stdlib.h>/* --- */int a;
#define LOKI 123
#define IKOL 123
#
void main()
{ //ask
int a,b ;/* bbb */
a=0;/* ccc */ /*
a\n
a */
/* ddd */ /* ooo
a\n
a */
a=0 ;/* eee */ /* */ /* */
//aaa
b=a ;//
b=a ; /* b */b=b;
printf( "\" " ) ;
b=1 ;
while(a!=b)
{ a=b ;
}
// printf( "%d\n",LOKI ) ;
/*/
int g;
*/
}
正しくは
コメント行 = 10
空白行 = 0
シャープ行 = 4
中カッコ行 = 3
なのですが
コメント行が9
中カッコ行が2になってしまいます。
<test2>
/**/#include <stdio.h>#include <stdlib.h>/* --- */int a;
#define LOKI 123
#define IKOL 123
#
/**/#define AA 123/***/
//#define BB 456
#define CC 789 /*
#define DD 741
*/
void main()
{ //ask
int a,b ;/* bbb */
a=0;/* ccc */ /*
a\n
a */
/* ddd */ /* ooo
a\n
a */
a=0 ;/* eee */ /* */ /* */
//aaa
b=a ;//
b=a ; /* b */b=b;
printf( "\" " ) ;
b=1 ;
while(a!=b)
{ a=b ;
}
// printf( "%d\n",LOKI ) ;
/*/
int g;
*/
}
int main2()
{ int j;/*
*/ int i;/***//**//*
int bb;
*/
// int cc;
for (i = 9; i< 10; i++) {
/**/{/**/ printf("%d\n", i);
}} // aaaa
/**/}}
こちらは正しくは
コメント行 = 16
空白行 = 2
シャープ行 = 6
中カッコ行 = 5
なのですが
中カッコ行が2になってしまいます。
こちらはなぜかコメントは正常でした。
どこに問題があるか教えていただけないでしょうか?
またファイル内容がEOFのみの1行だけの場合
上手く処理出来ません(泣
最初の1文字を上手く取れてないんでしょうか?
お力添えよろしくお願いいたします。
Re:ソースコードの行数
途中経過を表示させて確認していますか?
printfデバッグすれば、どの時点で自分の思い描くとおりに動いていないかすぐにわかると思いますよ。
http://funini.com/kei/c/debug.shtml
printfデバッグすれば、どの時点で自分の思い描くとおりに動いていないかすぐにわかると思いますよ。
http://funini.com/kei/c/debug.shtml
Re:ソースコードの行数
>backChar = fgetc(fp);
これはまずいのでは?
backCharはコメントの開始を判定するのに使っているだけなので'/'以外
の文字でもセットしておいて下さい。
>後はEOF行だけの時の処理ですが、 これも力技しかないのかなぁと。
EOFを読み込んだときどのフラグも立っていなかったらEOFだけの行と判定するとか・・
EOFを読み込んだときのbackCharが'\n'ならEOFだけの行と判定するとか・・
(これをやるならbackCharの初期値は'\n'が適当ですね)
それから'#'が来たら'\n'が来るまで読み飛ばさないといけないのでは?
ソースコードをざっと見てみましたが、できているところとできていないところが
混ざり合っているように見えました。
今のソースは捨てて、最初から作りなおしてみてはどうでしょうか?
その時に一気に作りたいものの仕様を満たすものを作ろうとするのではなく、
まずは空白のみの行数とそれ以外の行数を正確にカウントできるものを目指して下さい。
(合計すれば総行数も出てきますね)
このときに、前にも言った
「ファイルから読みとった文字を1文字ずつコンソール画面に表示していき、
改行文字またはEOFが来たら、その行が何の行と判定されたかを表示していけば 」
を実践して下さい。
これがMistさんのおっしゃられているprintfデバッグです。
途中経過ではバグっているのに最終結果だけは自分の想定通りというようなケースも
考えられますので・・・
ここまでの事がきちんと出来るようになったら、今度は空白のみの行数、コメントのみの行数、
それ以外の行数を正確にカウントできるように仕様を拡張していきましょう。
このような事を実践することで自分の書いたソースコードの中でできている部分と
問題がありそうな部分を切り離して考える事ができるようになります。
miiさんの質問を見ていると、これができていません。
これはまずいのでは?
backCharはコメントの開始を判定するのに使っているだけなので'/'以外
の文字でもセットしておいて下さい。
>後はEOF行だけの時の処理ですが、 これも力技しかないのかなぁと。
EOFを読み込んだときどのフラグも立っていなかったらEOFだけの行と判定するとか・・
EOFを読み込んだときのbackCharが'\n'ならEOFだけの行と判定するとか・・
(これをやるならbackCharの初期値は'\n'が適当ですね)
それから'#'が来たら'\n'が来るまで読み飛ばさないといけないのでは?
ソースコードをざっと見てみましたが、できているところとできていないところが
混ざり合っているように見えました。
今のソースは捨てて、最初から作りなおしてみてはどうでしょうか?
その時に一気に作りたいものの仕様を満たすものを作ろうとするのではなく、
まずは空白のみの行数とそれ以外の行数を正確にカウントできるものを目指して下さい。
(合計すれば総行数も出てきますね)
このときに、前にも言った
「ファイルから読みとった文字を1文字ずつコンソール画面に表示していき、
改行文字またはEOFが来たら、その行が何の行と判定されたかを表示していけば 」
を実践して下さい。
これがMistさんのおっしゃられているprintfデバッグです。
途中経過ではバグっているのに最終結果だけは自分の想定通りというようなケースも
考えられますので・・・
ここまでの事がきちんと出来るようになったら、今度は空白のみの行数、コメントのみの行数、
それ以外の行数を正確にカウントできるように仕様を拡張していきましょう。
このような事を実践することで自分の書いたソースコードの中でできている部分と
問題がありそうな部分を切り離して考える事ができるようになります。
miiさんの質問を見ていると、これができていません。
Re:ソースコードの行数
Mistさんドラさんありがとうございます。
提出日が月曜なので間に合うかどうかわかりませんが、
新しく作ってみようと思います!
わからなくなったらまた質問すると思うのでよろしくお願いします。
提出日が月曜なので間に合うかどうかわかりませんが、
新しく作ってみようと思います!
わからなくなったらまた質問すると思うのでよろしくお願いします。
Re:ソースコードの行数
提出期限が近そうなので、少しお手伝い。
ただし、最初の考えかたNo44014の添付ファイルを使ってです。
上の赤いコメントにしたところが、その処理です。これくらいは、自分で考えられると思い
わざと、放っておきました。
次に問題になったのは、No44384のファイルでコメント行の数があわないという件です。
これは、
/*/
int g;
*/
の場合が、チェックからもれていました。
/*の*が次の*/とダブって認識したのが原因です。
そこで、カウンタを設けて、1文字読み飛ばすようにしました。
これが、黄色文字の部分です。
なんで、最初の方法で最後まで頑張らないんだろ?
fgetcが複数の箇所に出てくるのは、好きじゃないなぁ。
ただし、最初の考えかたNo44014の添付ファイルを使ってです。
int Cstep(const char *filePath, FILE *fp) { int currentChar; // 現在の文字 int backChar = 0; // 1個前の文字 int commentFlag = 0; // 各コメント状態を表す (0の場合非コメント状態) int countFlag = 0; // 複数行コメントの終了判定 (0の場合非コメント状態) int spaceFlag = 0; // 空白又はTABを判定 (0の場合空白又はTAB状態) int startFlag = 1; // 最初の文字か判定 (0の場合2個目以降の文字) int lineCnt = 0; // 総ステップ数 int nonRealCnt = 0; // 実ステップ数に含めない数 int sharp_flag = 0; int brace_flag = 0; int sharpLines = 0; int braceLines = 0; int cF=0; while ((currentChar = fgetc(fp)) != EOF) { // 単一行コメントの開始 if (currentChar == '/' && backChar == '/') { commentFlag = 1; } // 複数行コメントの開始 else if (currentChar == '*' && backChar == '/') { commentFlag = 2; cF=2; } // 複数行コメントの継続 else if (currentChar == '/' && backChar == '*' && cF==0) { commentFlag = -1; countFlag = 2; } if(cF>0) cF--; // 単一行コメント終了判断 if (commentFlag == 1 && backChar == '\n') { commentFlag = 0; } // 複数行コメント終了判断 else if (commentFlag == -1) { // 複数行コメントが非コメント状態 if (countFlag == 0) { commentFlag = 0; } // 複数行コメント継続状態 else { countFlag--; } } // 非コメント状態又は読み取った文字の1個前が改行文字のいずれか if ((startFlag == 0 && commentFlag == 0) || backChar == '\n') { // 1個前の文字が改行文字だった場合 if (backChar =='\n') { lineCnt++; if (sharp_flag == 1) { sharpLines++; } if (brace_flag == 1) { braceLines++; } // コメント又は空白行であれば if (spaceFlag == 0) { nonRealCnt++; } spaceFlag = 0; sharp_flag = 0; brace_flag = 0; } // 1個前の文字が空白又はTAB文字文字以外の場合 else if (!isspace(backChar)) { // 1個前の文字が括弧の場合 if (backChar == '{' || backChar == '}') { if (brace_flag == 0) { brace_flag = 1; } } else { brace_flag = 2; } spaceFlag = 1; } if (backChar == '#') { sharp_flag = 1; } } startFlag = 0; backChar = currentChar; } Print(filePath, lineCnt, nonRealCnt, sharpLines, braceLines); // 最初の文字でなく if (startFlag == 0) { // 1個前の文字が改行文字の場合 // if (backChar =='\n') { lineCnt++; //nonRealCnt++; // } // 空白又はTAB状態の場合 if (spaceFlag == 0) { nonRealCnt++; } if (sharp_flag == 1) { sharpLines++; } if (brace_flag == 1) { braceLines++; } } // 表示 Print(filePath, lineCnt, nonRealCnt, sharpLines, braceLines); return 0; }あの段階で問題になったのはEOFのみの行をカウントしないようにするということでした。
上の赤いコメントにしたところが、その処理です。これくらいは、自分で考えられると思い
わざと、放っておきました。
次に問題になったのは、No44384のファイルでコメント行の数があわないという件です。
これは、
/*/
int g;
*/
の場合が、チェックからもれていました。
/*の*が次の*/とダブって認識したのが原因です。
そこで、カウンタを設けて、1文字読み飛ばすようにしました。
これが、黄色文字の部分です。
なんで、最初の方法で最後まで頑張らないんだろ?
fgetcが複数の箇所に出てくるのは、好きじゃないなぁ。
Re:ソースコードの行数
> なんで、最初の方法で最後まで頑張らないんだろ?
ここまでの流れを見ての私の感想。
デバッグが出来ていない(処理の途中経過を追えていない)ので微細な間違いが修正できない。
↓
やり方自体に問題があるんだ!(この方法では無理)という結論になる。
↓
違うやり方で解決しようとする。
↓
大幅に修正する。
↓
正しかったところまで動かなくなる。
↓
気づいた範囲で修正してある程度までは動くけど、微細な間違いを修正できないから終わらない。
↓
以下、エンドレス
ここまでの流れを見ての私の感想。
デバッグが出来ていない(処理の途中経過を追えていない)ので微細な間違いが修正できない。
↓
やり方自体に問題があるんだ!(この方法では無理)という結論になる。
↓
違うやり方で解決しようとする。
↓
大幅に修正する。
↓
正しかったところまで動かなくなる。
↓
気づいた範囲で修正してある程度までは動くけど、微細な間違いを修正できないから終わらない。
↓
以下、エンドレス
Re:ソースコードの行数
nonさんありがとうございます。
どうしてもわからないのですが、
過去レス見たんですが、あの時はputcharで出力したくないとのことでしたが、
どういうことなんでしょうか?
上手く説明できずに困っています(泣
どうしてもわからないのですが、
else if (currentChar == '/' && backChar == '*' && cF==0) { commentFlag = -1; countFlag = 2; }のカウントフラグ = 2の部分ですが、どうして2にするのでしょう?
過去レス見たんですが、あの時はputcharで出力したくないとのことでしたが、
どういうことなんでしょうか?
上手く説明できずに困っています(泣
Re:ソースコードの行数
No43645の再掲です。
> では次に、/*~*/のコメントです。
> 基本的な考え方は//と同じです・
> /*のとき cntOff = 2 にしましょう。
>
> */のとき cntOff=0 にすればよさそうですが、まだ*/の2文字を
> 出力したくないので、int count を用意して
> cntOff=-1にしておいて、
> count=2にします。
>
> cntOff=-1のとき
> count==0になったらcntOff=0にします。
> そうでなければ、countを減らします。
意味がわからないのなら、countFlag = 0;
でどう動作するのか試してみればいい。
> では次に、/*~*/のコメントです。
> 基本的な考え方は//と同じです・
> /*のとき cntOff = 2 にしましょう。
>
> */のとき cntOff=0 にすればよさそうですが、まだ*/の2文字を
> 出力したくないので、int count を用意して
> cntOff=-1にしておいて、
> count=2にします。
>
> cntOff=-1のとき
> count==0になったらcntOff=0にします。
> そうでなければ、countを減らします。
意味がわからないのなら、countFlag = 0;
でどう動作するのか試してみればいい。
Re:ソースコードの行数
>意味がわからないのなら、countFlag = 0;
でどう動作するのか試してみればいい。
そうですよね(汗
なぜ気付かなかったんだろう。。。orz
早速やってみます!
ありがとうございます。
でどう動作するのか試してみればいい。
そうですよね(汗
なぜ気付かなかったんだろう。。。orz
早速やってみます!
ありがとうございます。
Re:ソースコードの行数
後は1文字だけでEOF行だけの場合の処理になりました。
a[EOF]
この場合必ずspaceFlagが0なので、この行が空白行扱いになってしまいます。
これを回避するにはどうすればいいでしょうか?
文字の長さを取得して1行かつ1文字だったらという条件でやろうとしたのですが、
1文字が2バイト文字だと2文字扱いになるのでどうしようかと思いまして。
a[EOF]
この場合必ずspaceFlagが0なので、この行が空白行扱いになってしまいます。
これを回避するにはどうすればいいでしょうか?
文字の長さを取得して1行かつ1文字だったらという条件でやろうとしたのですが、
1文字が2バイト文字だと2文字扱いになるのでどうしようかと思いまして。
Re:ソースコードの行数
"コンパイルが通る"という仕様を忘れておりました。
ということなので1文字等に関しては無視してOKとのことでした。
管理人さん、nonさん、たかぎさん、ドラさん、Mistさん
本当にありがとうございました。
特にnonさんにはかなりご迷惑をおかけして申し訳ありませんでした。
ここで質問者の回答が出来るくらいにCを勉強したいと思います。
また来るかもしれませんが、その際はよろしくお願いします。
ということなので1文字等に関しては無視してOKとのことでした。
管理人さん、nonさん、たかぎさん、ドラさん、Mistさん
本当にありがとうございました。
特にnonさんにはかなりご迷惑をおかけして申し訳ありませんでした。
ここで質問者の回答が出来るくらいにCを勉強したいと思います。
また来るかもしれませんが、その際はよろしくお願いします。