0

I wrote a java program which scans and finds Executable lines of codes (ELOC), blank lines of codes(BLOC) and comments (CLOC) for only java and c++ codes. Following is my code:

 if(extension.contains("java") || extension.contains("c++"))
                {
                    Scanner input = new Scanner(fileObject);
                    while(input.hasNext())
                    {
                        String s = input.nextLine();
                        if(s.length()==0)
                        {
                            bloc++;
                        }
                        else if(s.contains("/*") || s.startsWith("/*"))
                        {
                            cloc++;
                            while(!s.contains("*/"))
                            {
                                cloc++;
                                s = input.nextLine();
                            }
                        }
                        else if(s.contains("//"))
                        {
                            cloc++;
                        }
                        else
                        {
                            eloc++;
                        }
                    }//while
                    System.out.println("ELOC: "+(eloc));
                    System.out.println("Blank Lines: "+bloc);
                    System.out.println("Comment Lines: "+cloc);
                }

I ran different java and c++ source codes but it does not always give the correct answer. What Can I do to make it better? Is there any java code online that I can use?

For this question, I'm only counting the executable lines of codes. If a line looks like following:

int x=0;//some comment

then the line above should be counted as one executable line. Following is my updated code:

String extension=getExtension(fileObject.getName());
            if(extension.contains("java") || extension.contains("c++"))
            {           
                Scanner input = new Scanner(fileObject);
                String s;
                while(input.hasNext())
                {
                    s = input.nextLine().trim();
                    eloc++;
                    if(s.equals(""))
                    {
                        bloc++;
                    }
                    if(s.startsWith("//"))
                    {
                        cloc++;     
                    }
                    if(s.contains("/*") && !s.contains("*\\"))
                    {
                        cloc++;
                        while(!s.contains("*/"))
                        {
                            cloc++;
                            eloc++;
                            s = input.nextLine();
                        }
                    }
                    else if(s.contains("/*") && s.contains("*\\"))
                    {
                        cloc++;
                    }
                }
                System.out.println("Total number of lines: "+eloc);
                System.out.println("ELOC: "+(eloc-(cloc+bloc)));
                System.out.println("Blank Lines: "+bloc);
                System.out.println("Comment Lines: "+cloc);
            }

Any comment/advice will be appreciated..Thanks!

sap
  • 1,141
  • 6
  • 41
  • 62
  • http://stackoverflow.com/questions/2184999/sloc-for-java-projects – Josh Lee Aug 10 '11 at 18:28
  • 1
    You said it "does not always give the correct answer." When it is wrong, how is it wrong? Can you give an example? – George Cummins Aug 10 '11 at 18:30
  • I'm comparing my results against locmetrics.com and not getting the same results. – sap Aug 10 '11 at 18:59
  • 3
    @Sarah How do you know locmetrics.com gets it right and you get it wrong? You should start by clearly defining what consitutes each type of line, and devise test cases that you can run your code against. – Nick Johnson Aug 11 '11 at 01:46
  • That's a great suggestion. I updated my question/code above. Thanks – sap Aug 11 '11 at 14:32

3 Answers3

4

On a Unix system you could simply use cloc. This gives you the following output:

src$ cloc .
51 text files.
51 unique files.                              
285 files ignored.

http://cloc.sourceforge.net v 1.53  T=0.5 s (82.0 files/s, 5854.0 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Java                            39            618            119           2145
XML                              2              8              0             37
-------------------------------------------------------------------------------
SUM:                            41            626            119           2182
-------------------------------------------------------------------------------

Code lines do not contain comments or blanks, but do include something like block brackets or import statements using cloc for Java.

There are other tools available, but this is the most simple if you just need to count the code lines. Hope this helps.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Stefan Schubert-Peters
  • 5,419
  • 2
  • 20
  • 21
1

Blank lines might not have a length of zero. Their content might contain whitespace, at least mine do. Try trimming it before checking length to get a more accurate count.

The only thing else I can say is that your numbers will be off if you have lines that contain code and comments. It looks like the code you have now will consider an entire line a comment if it even partially contains a comment. For example:

Validate(input); // This validates user input

This will not be counted as ELOC but as CLOC. This may not be a problem if the coding style is more like this:

// Validate user input
Validate(input);

But not every developer will use the second way. I personally use a mix of both depending on context.

Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188
0

Example which does not produce expected counts:

int a;
a = 7; // comment, yeah
int b /* my favorite variable */ = 3;
executeMethod(dataField,
   moreData,excitingBoolean,resultSetFromMyGrandma,
   anotherParameterTakingAnotherWholeLine);

Your program is not handling comments or multi-line statements very gracefully.

Edit

I would suggest parsing it fully into a tree, recognizing comments and executable lines of code by the grammar that Java compilers use, and counting from there. There are plenty of exceptions that simple checks might skip over. Additionally, consider the line:

String commentCodeFun = " // not a real comment ";

It's a nightmare for your current approach

Atreys
  • 3,741
  • 1
  • 17
  • 27
  • how do you suggest I handle a line like : "a = 7; // comment, yeah" or "int b /* my favorite variable */ = 3;" – sap Aug 10 '11 at 18:59
  • Shouldn't they increment both eloc and cloc? – Atreys Aug 10 '11 at 19:02
  • true, but what would I put in my if statement? – sap Aug 10 '11 at 19:05
  • 1
    I would suggest parsing it fully into a tree, recognizing comments and executable lines of code by the grammar that Java compilers use, and counting from there. There are plenty of exceptions that simple checks might skip over. What about the line `String commentCodeFun = " // not a real comment ";`? It's a nightmare for your current approach – Atreys Aug 10 '11 at 19:09
  • I don't really care about comments, I need to find only ELOCS. – sap Aug 10 '11 at 19:16
  • Then you're only concerned about lines which, after being trimmed, *start with* (not contain) `//` or that are not wholly within the `/* ... */` pair. For the multi-line comments, extra logic will need to be examined. – Atreys Aug 10 '11 at 19:19
  • @sarah let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2337/discussion-between-atreys-and-sarah) – Atreys Aug 10 '11 at 19:19