C++ getline to ignore comments "//"

legcramp

[H]F Junkie
Joined
Aug 16, 2004
Messages
12,401
Code:
while(getline(infile,lines)) 
	{

		if(lines.empty())  
			{
				continue;
					
			}
		if(lines.find("//") == true)
			{
				continue;
			}
		
		++linecount;


I got the counter to skip spaces flawlessly, but skipping the comments in the line count isn't going very well.

Any help is appreciated!
 
Sorry, forgot to mention that I just want the counter to skip the line if the "//" is in front of the line.

Right now, the line is skipped for example:

cout << "Hello World" << endl; //comment here


But I only want it to skip the line if:

//comment here ...........
 
The find method seems to be looking for the substring anywhere in the string and returning a true value (presumably the position where it was found). If that's not the behavior you want, then you'll have to use a method that does what you need.
 
Meh, try this... was bored. I assume this is some sort of "count lines of code" program... running this program on this cpp file returns 30 lines

Your "empty" check failed if they had random spaces/tabs on the line

Code:
#include <iostream>
#include <fstream>
#include <string>

unsigned count_lines( std::string const& filepath )
{
  unsigned linecount = 0;
  const std::string whitespace(" \t\n\r");
  std::string lines;
  std::ifstream infile( filepath );
  
  while( std::getline( infile, lines ) ) 
  {
    std::size_t first_nonws = lines.find_first_not_of( whitespace );
    
      // skip empty lines
    if( first_nonws == std::string::npos ) {
      continue;
    }
      // skip c++ comments
    if( lines.find("//") == first_nonws ) {
      continue;
    }
      // skip preprocessor directives (doesn't work on multiline)
    if( lines.find("#") == first_nonws ) {
      continue;
    }

    ++linecount;
  }
  return linecount;
}

int main( int arg_c, char** arg_v )
{
  if( arg_c == 2 )
  {
    std::cout << count_lines( arg_v[1] ) << std::endl;
  }
  return 0;
}
 
Code:
while(getline(infile,lines)) 
	{

		if(lines.empty())  
			{
				continue;
					
			}
		if(lines.find("//") == true)
			{
				continue;
			}
		
		++linecount;


I got the counter to skip spaces flawlessly, but skipping the comments in the line count isn't going very well.

Any help is appreciated!

In your while loop:

Code:
if(lines.find("//") == true)

This line is not doing what you think it is. Find is not going to return a bool, but rather a size_t. size_t is an integer representing the index in the string where the match is found.

Since it isn't a bool, when you do compare it with a bool it is implictly converted into a bool before the comparison is made. When this happens, 0 becomes false and anything other than zero becomes true.

If a line begins with "//", when you do lines.find("//") it's going to return zero, which is going to be converted to false. If "//" appears anywhere else, it will return that position, which is true, or if it doesn't appear it will return -1 (std::string::npos), which is also true.

Therefore, if the string begins with "//", lines.find("//") is going to be false, and if it doesn't start with "//", lines.find("//") is going to be true. If you invert your logic and change it to "if (lines.find("//") == false)" it should work, but for clarity and understanding I would encourage you to compare actual values, so "if (lines.find("//") == 0)" rather than leaving a misleading expression in your code.
 
You need to decide what behavior you really want, and write some code to parse it as appropriate. Is it OK if there's whitespace before the //? If so, you need to account for that.

Part of it depends on what you want to do - if you're trying to actually parse a file into some meaningful syntax, it may be worth looking into doing a proper token-based parser/lexer; there are plenty of tools out there to make that process simple.
 
Thanks everyone, I ended up counting semi-colons instead for a logical lines of code count.
 
Hmm, I don't think that's quite accurate, but if that's what you're going for...

Code:
  for(;;);

Which would have 3 lines of code counted, in reality it's 1 or 0... and useless (just putting an example out there)

Code:
  while( ( Node* node = FindNextNode() ) && node->value == 27 ) {
  }

Would count as 0 lines of code, because there's no semi-colons.

The only thing you need to add to my implementation is check for lines with just curly braces and you would have covered almost everything...

Or you could use cloc?
 
Back
Top