1

I'm developing a tool to analyse and give some statistics about other people's source code, the tool will be able to recognize many things in the code! Right now am stuck at counting the number of comments on the code, my current code is:

 public static void main(String[] args) {

    String line = "";
    int count = 0;
    try {
        BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
        while ((line = br.readLine()) != null) {
            if (line.startsWith("//")) {
                count++;
            } else if (line.startsWith("/*")) {
                count++;
                while (!(line = br.readLine()).endsWith("'*\'")) {
                    count++;
                    break;
                }
            }
        }
        br.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println("count=" + count);
}

To check the code, I am using a test file. But the code is giving me the wrong result in both files, for example; I am getting three in the following file

Yes
//comment
yes
yes
/*
if
random
test
test
*/

While the answer should be two comments!

In the following file, it's showing me that I have five comments while I still actually have two

Yes
//comment
yes
yes
/*
if
random
test
test
/*
*/
Draken
  • 3,134
  • 13
  • 34
  • 54
user5923402
  • 217
  • 3
  • 12
  • Not an answer, but related: take a look at [Sonar](http://www.sonarqube.org/) and [Codepro AnalytiX](https://developers.google.com/java-dev-tools/codepro/doc/features/metrics/metrics) – Nivas Feb 18 '16 at 20:14
  • Your code doesn't count the number of comments, but (attempts to count) the number of comment lines. The `"'*\'"` should be `"*/"`. Also, in the inner loop, you don't check for NULL lines. It's better to stick to 1 loop, and set a boolean to indicate if you are inside a multi-line `/* .. */` comment. – Kenney Feb 18 '16 at 20:14
  • BTW comments can appear anywhere in a line. in fact you can have more than one comments on a line. – Peter Lawrey Feb 18 '16 at 20:23
  • @PeterLawrey how? wouldn't that be counted as single line? – user5923402 Feb 18 '16 at 20:25
  • 2
    @user5923402 `int /*this is an int*/ x = /*default value*/ 3; //initialization` is valid Java code. – Nivas Feb 18 '16 at 20:26
  • @Nivas I would upvote 3x if I could. ;) – Peter Lawrey Feb 18 '16 at 20:33
  • @Nivas I see what you mean now! I didnt think about that before! – user5923402 Feb 18 '16 at 20:34
  • @Nivas the tools you mentioned are really helpfull! is there anyway to merge them, with my code? or that would save alot of time, specially that am doing my thesis and the main topis is about testing, but these things are taking more time that I assumed! – user5923402 Feb 18 '16 at 22:45
  • @PeterLawrey I understand completely what you are saying, but this is not what I'm looking for, as I have no plan to count the number of comments "blocks of comments" rather than the number of comments lines! lets take a simple case as an example: 23. System.out.println("what ever"); // this prints "what ever" in this case, would you consider the line nr.23 as a part of the source code or as comment line? – user5923402 Feb 18 '16 at 23:18

6 Answers6

5

The whole approach is flawed. You need to parse the source file properly, at least you need to keep track properly of quotes and nesting of "/*". Note that any comment character combination can appear inside statements like:

 System.out.println("// this is *not* a line comment");
 String s = "*/ this is not the end of a block comment";

and so on. Then there is the weird behavior with character escape sequences being processed before the file is interpreted:

    \u002F* this is a valid comment */

Its not that easy to determine what is a comment and whats not :) I strongly suggest you look for an open source parser solution for java sources.

Durandal
  • 19,919
  • 4
  • 36
  • 70
  • 1
    And now someone is making sense. :) – m-albert Feb 18 '16 at 20:38
  • Let me google that, and propably I will come with more questions :) – user5923402 Feb 18 '16 at 21:12
  • But regarding the example you gave; System.out.println("// this is *not* a line comment"); of course its not a comment and that is why I have a condition if(line.startsWith("//")); wont that help? – user5923402 Feb 18 '16 at 22:52
  • @user5923402 Line comments can start *anywhere* on the line. If the comment were after the semicolon after the statement it would be a valid comment. What makes it not a comment here is just that its contained *in* a statement. I'd say line comments *rarely* start at the beginning of the line, considering that its normal to indent code and also that these are often placed after a statement on the same line. – Durandal Feb 18 '16 at 23:06
  • @Durandal I understand completely what you are saying, but this is not what I'm looking for, as I have no plan to count the number of comments "blocks of comments" rather than the number of comments lines! lets take a simple case as an example: 23. System.out.println("what ever"); // this prints "what ever" in this case, would you consider the line nr.23 as a part of the source code or as comment line? – user5923402 Feb 18 '16 at 23:15
  • 2
    @user5923402 For me there is no question if a *line* is a comment or a statement - the concept of *line* means nothing except that a linefeed terminates a line comment. So for your example line 23, the answer is: its both source and comment. Also, counting "lines" is not a useful metric in a language where linefeeds are optional. In the extreme case you could write an entire *class*'s source in a single line. – Durandal Feb 19 '16 at 15:59
0

I haven't tested your code however, I believe this should work :

public static void main(String[] args) {

    String line = "";
    int count = 0;
    try {
        BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
        while ((line = br.readLine()) != null) {
            if (line.startsWith("//")) {
                count++;
            } else if (line.startsWith("/*")) {
                count++;
                while ((line = br.readLine())!=null && !line.endsWith("'*\'"));
            }
        }
        br.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println("count=" + count);
}

When you meet the /* you should increment the counter and skip the comment section.

Youssef NAIT
  • 1,362
  • 11
  • 27
  • thanks for your answer, I really appreciate it! But the answer is giving an error: Exception in thread "main" java.lang.NullPointerException at countcomment.CountComment.main(CountComment.java:33) Java Result: 1 at: while (!(line = br.readLine()).endsWith("'*\'")); – user5923402 Feb 18 '16 at 20:22
  • for the first two files it works, but just a small edit in the file like: Yes //comment yes yes /* if random test test */ test /**/ its still giving 2 – user5923402 Feb 18 '16 at 20:32
  • My intention was to show you the mistake in your code, if you want a code that handles all cases I think that you still got, a lot more cases to manage. – Youssef NAIT Feb 18 '16 at 20:37
0

I think you have a problem in that comments can occur inside or at the end of a line as well...

public static void main(String[] args) {

    String line = "";
    int count = 0;
    try {
        BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
        while ((line = br.readLine()) != null) {
            if (line.contains("//")) {
                count++;
            } else if (line.contains("/*")) {
                count++;
                while (!line.contains("*/") && !(line = br.readLine()).contains("*/"));
            }
        }
        br.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println("count=" + count);
}

Of course the problem here is what if the "//", "/* " or "*/" sequences occur within quoted text....?

m-albert
  • 1,089
  • 8
  • 15
0

Guys here is a easy solution. Just download the cloc software from this link for windows. This software support every language & can accept folder of files also. Put your folder and cloc in same place and open cmd type this command

cloc-(version no).exe (folder name)
cloc-1.64.exe main

and have the no of lines, blank line and total no of lines in the code.

RESULTS:

For more detail see this: http://cloc.sourceforge.net/

waqas ali
  • 1,238
  • 1
  • 11
  • 17
0
    enter code here
public class FilterInputStreamDemo {
public static void main(String[] args) {

    String line = "";
    int comment_count = 0;
 int line_count = 0;
int single_comment_count = 0;
int multiple_comment_count = 0;
    try {
        BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
        while ((line = br.readLine()) != null) {
    line_count++;
            if (line.startsWith("//")) {
                comment_count++;
        single_comment_count++;
            } else if (line.startsWith("/*")) {
                comment_count++;
        multiple_comment_count++;
                while (!(line = br.readLine()).endsWith("'*\'")) {
                    comment_count++;
            multiple_comment_count++;
                    break;
                }
            }
        }
        br.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println("comment_count=" + comment_count);
}
}
0
package com.usaa.training;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class CommentsReading {
public static void main(String[] args) {

    String line = "";
    int number_of_blocks = 0;
    int comment_count = 0;
 int line_count = 0;
 int TODO = 0;
int single_comment_count = 0;
int multiple_comment_count = 0;
    try {
        File file = new File("C:\\code\\InvolvedPartyBasicInfoMapper.java");
        BufferedReader br = new BufferedReader(new FileReader(file));
        while ((line = br.readLine()) != null) {
    line_count++;
            ;
            if (line.contains("//")) {
                 if (line.contains("TODO")){
                     TODO++;
                 }
                comment_count++;
        single_comment_count++;
            } else if (line.contains("/*") ) 
            {
                if (line.contains("TODO")){
                 TODO++;
             }
                comment_count++;
        multiple_comment_count++;
      if (line.endsWith("*/"))
      {
          break;
      }

                while (!(line = br.readLine()).endsWith("'*/'") )
                {
                    line_count++;
                    comment_count++;
            multiple_comment_count++;
            if (line.endsWith("*/"))
            {
                number_of_blocks++;
                break;
            }


                }
            }
        }
        br.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("Total # of Lines  = " + line_count);
    System.out.println("Total # of Comment Lines= " +comment_count);
 System.out.println("Total # of Single line Comments= " +single_comment_count );
 System.out.println("Total # of Comment lines with Block Comments = " +multiple_comment_count );

    System.out.println("Total # of Block line Comments = " +number_of_blocks);

    System.out.println("No of TODO's  = " +TODO);
}
}