これは、Ruby/Perl/Awk などのフリップフロップを思い出させます。を使用する必要はありませんStringTokenizer
。コメントのある行数をカウントするには、状態を維持する必要があります。
あなたはコメントブロックの中にいます。すべての文字を印刷または収集し始めます。全体に a が表示されるとすぐに*/
、コメント ブロック スイッチを切り替えます。状態 2 に切り替えます。
/*
に遭遇し、状態 1 に戻るまで、すべてを拒否します。
このようなもの
public static int countLines(Reader reader) throws IOException {
int commentLines = 0;
boolean inComments = false;
StringBuilder line = new StringBuilder();
for (int ch = -1, prev = -1; ((ch = reader.read())) != -1; prev = ch) {
System.out.println((char)ch);
if (inComments) {
if (prev == '*' && ch == '/') { //flip state
inComments = false;
}
if (ch != '\n' && ch != '\r') {
line.append((char)ch);
}
if (!inComments || ch == '\n' || ch == '\r') {
String actualLine = line.toString().trim();
//ignore lines which only have '*/' in them
commentLines += actualLine.length() > 0 && !"*/".equals(actualLine) ? 1 : 0;
line = new StringBuilder();
}
} else {
if (prev == '/' && ch == '*') { //flip state
inComments = true;
}
}
}
return commentLines;
}
public static void main(String[] args) throws FileNotFoundException, IOException {
System.out.println(countLines(new FileReader(new File("/tmp/b"))));
}
上記のプログラムは、空の行のコメントまたはのみ/*
またはその中にある行を無視*/
します。また、文字列トークナイザーが失敗する可能性のあるネストされたコメントを無視する必要があります。
サンプルファイル /tmp/b
#include <stdio.h>
int main()
{
/* /******* wrong! The variable declaration must appear first */
printf( "Declare x next" );
int x;
return 0;
}
1 を返します。