C ++ calculates the number of lines commented by code, valid lines of code, public lines commented by code, and number of functions.
Problem Source: a small project in the summer of 14 years encountered such a problem, requiring statistics on the number of comments in the C ++ code, the number of valid code lines, and the number of comments in the code, and the number of functions. The following is a brief explanation of the problem. 1) Number of commented rows: refers to the lines with comments, including public lines with code and comments (for example, 3, 4, 15, 22 ...) 2) valid code line: refers to the line with code, including the public lines with code and comments (such as:, 25 ....) 3) code comments public line: refers to the lines with code and comments (for example, 4, 15 ...) 4) number of functions: Needless to say, it is clear. The following code is used to demonstrate the annotation: Copy code 1 # include <stdio. h> 2 3 // follow is a common line 4 void swap (char * p/* = NULL */) 5 {6 printf ("this is a function/* is not comments */"); 7} 8 9 int main (void) 10 {11 int a = 10; 12 int B; 13 char * p = NULL; 14 15 swap (p); // common line16 if (10 = a) 17 {18 printf ("is not function; // is not comments "); 19} 20 // pure comments/* no use */21 22/* a = 5; 23 printf (" not use \ n "); */24 25 B = 3;/* I'm a comment */a = 5;/* comments line26 pure // comments line ;"*/...... "look there */27 printf (" test \ "escape char"); 28 // and the follow, maybe affect the count of function29 if (* p = '{') 30 {31 printf ("the '{' is a question \ n"); 32} 33 // 34 35 return 0; 36} copy the code snippet above the code, the following figure shows the possible comments. Next, let's analyze the positions where the comments appear: 1. "//" Double slash comment 1) The comments may appear in the row header, for example: 3rd rows; 2) may appear at the end of the row, for example, 15th rows; Note: 18th rows, 26th rows. In row 3, the comment is invalid; in Row 3, the comment is invalid; // In/**/the comment is invalid. 2. "/**/" slash star comment 1) may appear in function parameters, for example, row 4th; 2) may comment a paragraph, for example, Row 22, 23; 3) it may also appear in the middle of the Code, such as 25 or 26 lines of complex comments; Note: 20th rows, 26th rows. Row 3,/**/In // comment, invalid. Row 3, with one */located in "", */invalid. Well, after location analysis, let's analyze how to design the algorithm: 3. Specific Algorithm Design Ideas 1) Solve the Problem of reading files. Here we use c ++ to read a file and read a row each time, put the read result in the string variable, so that the tail of the string variable is automatically '\ 0 '. We are used to judge the end of a row. 2) double quotation marks because the content in the double quotation marks is invalid, we can directly filter the content in the double quotation marks. (For specific implementation, see the code) 3) single quotation marks (for example, if (ch = '{')) the number of functions may be affected, so we need to filter single quotes. 4) Empty rows are the simplest. If string is null, It is empty rows. Including (\ t \ n \ r'' and so on, invalid characters, are considered empty rows ). 5) The "//" annotation is relatively simple. When it comes to //, statistics can be made. At the same time, the row does not need to be traversed, And the next row can be read directly. 6) "/**/" comments are troublesome. Here we use code tags and comments. We also set the number of rows to be counted only when the rows are traversed to the end of the row, this prevents a row from being counted multiple times. (For specific implementation, see Code) 7) the number of functions first describes the statistical logic. When we count functions, we only mark them with braces. It is represented by a stack. When it comes to left brackets, it goes to the stack. When it comes to right brackets, a left bracket is displayed. Knowing that the stack is empty, the number of functions is + 1. In this way, only the outermost pair {} is retained, and all the parentheses in the middle layer are offset. We thought about it again and simplified it. Instead of using a stack, we directly use a variable to represent the number of parentheses. in the case of left parentheses, ++ top, and right parentheses -- top, until top = 0, it is equivalent to the empty stack, the number of functions + 1. In fact, there is still a problem with the number of functions in the following code: for classes, struct, enumeration bodies, and global arrays, a function is counted. That is to say, the Code with braces ({}) in the external body of the function will be recognized as a function. The following is the implementation code: Copy code 1 # include <iostream> 2 # include <fstream> 3 # include <string> 4 using namespace std; 5 6 int main (void) 7 {8 string line = ""; 9 ifstream ifs; 10 ifs. open ("Test. cpp "); 11 if (! Ifs) 12 {13 cout <"file opening failed" <endl; 14 exit (0 ); 15} 16 ///////////////////////////////////// //// // 17 // mark: 18 int bSyh = 0, bXgx = 0, bHs =-1, bCode = 0, bZs = 0; 19 // "" ''// * {} 20 ////////////////////////// //// // 21 // Number: empty line comments code public function 22 int I, nKh = 0, nZs = 0, nDm = 0, nGg = 0, APLs = 0; 23 // 24 while (! Ifs. eof () 25 {26 I = 0; 27 getline (ifs, line); // read a row of files 28 bCode = 0; // No code for this row 29 bZs = 0; // This row has no comments 30 if (bXgx) // The bXgx slash star comments mark 31 bZs = 1; // note 32 for this row // filter invalid symbols 33 while (line [I] = ''| line [I] = '\ T' | line [I] = '\ R' | line [I] =' \ n ') 34 {35 + + I; 36} 37 // "The following is the empty row statistical area: Start" 38 if (! BXgx & line [I] = '\ 0') // empty row 39 {40 + + nKh; 41 continue; 42} 43 // "empty row statistics: end "44 while (1) 45 {46 // The first time you encounter double quotation marks, the quotation marks are not escape characters (\") 47 if (! BSyh & line [I] = '\ "' & (I> 0 & line [I-1]! = '\') | (I = 0) 48 {49 + I; 50 bSyh = 1; 51 continue; 52} 53 // "Double quotation marks are being shielded .... "54 if (bSyh) 55 {56 // "\" end "57 if (line [I] = '\"' & (I> 0 & line [I-1]! = '\') | (I = 0) 58 {59 bSyh = 0; 60} 61 else if (line [I] = '\ 0 ') // 62 {63 if (bZs) 64 + + nZs; 65 if (bCode) 66 + + nDm; 67 if (bZs & bCode) 68 + nGg; 69 break; 70} 71 + + I; 72 continue; 73} 74 // single quotation marks (avoid '{', '}') and non-escape characters \', skip 3 consecutive (second location) 75 if (line [I] = '\ ''& (I> 0 & line [I-1]! = '\') | (I = 0) 76 {77 I + = 3; 78 continue; 79} 80 // "// comment row" 81 if (! BXgx & line [I] = '/' & line [I + 1] = '/') 82 {83 if (bCode) // "there is code before, hybrid comment line "84 {85 + nZs; // comment 86 + nDm; // code 87 + nGg; // public 88} 89 else // pure comment row 90 {91 + + nZs; 92} 93 break; // jump out of the current row (that is, the internal while LOOP ), "//" after the code is not judged 94} 95 // "/* Comment start" 96 if (! BXgx & line [I] = '/' & line [I + 1] = '*') 97 {98 I + = 2; // skip/* symbol 99 bXgx = 1; // mark "/*" Start 100 bZs = 1; // "Notice comments" 101 continue; 102} 103 // "multi-line comments in progress .... "104 if (bXgx) 105 {106 // "*/end of comment" 107 if (line [I] = '*' & line [I + 1] = '/') 108 {109 ++ I; // "skip */" note that there is a ++ I; 110 bXgx = 0; 111} 112 else if (line [I] = '\ 0') // code before the end of the row 113 {114 if (bCode) // comments, that is, "hybrid row" 115 {116 + nDm; 117 + nZs; 118 + + nGg; 119} 120 else121 {122 + nZs; // "Pure annotation" 123} 124 break; 125} 126 + + I; 127 continue; 128} 129 if (line [I] = '\ 0 ') 130 {131 if (bZs) 132 + + nZs; 133 if (bCode) 134 + + nDm; 135 if (bZs & bCode) 136 + + nGg; 137 break; 138} 139 // "The following are all valid Code regions" 140 // "function count statistical regions: Start" 141 if (line [I] = '{') // record function 142 {143 + bHs; 144} 145 else if (line [I] = '}') // encounter a function right brace 146 {147 if (bHs = 0) // "discover a function" 148 + + AIS; 149 -- bHs; 150} 151 // "function statistics: End" 152 + I; 153 bCode = 1; // can be executed here, this row contains code 154} 155} 156 157 cout <"Note:" <nZs <endl; 158 cout <"Code:" <nDm <endl; 159 cout <"empty line:" <nKh <endl; 160 cout <"public:" <nGg <endl; 161 cout <"function: "