C++ 代码统计工具 & 判断一行代码是否为注释行

这两天接手了一个项目,项目定义了一种自己语法,所以有了判断注释的需求。

这里自己简单实现了一个,代码非常精简。


提供的注释语法和C++是一模一样的, 允许 // 和 /* */两种注释


两个问题:

1、如何判断某一行是否为注释行。

2、如何判断是否“进入”了注释段,也就是在/* */中间。


先说第2点,思路:从上往下,一行一行的检查。

用一个flag标识是否”进入”了注释,具体在一行当中,遇到/* flag 置1,遇到 */ 置0;这样即使一行中有多个/* */也不会判断错误。

比如  /*int x*/ printf(); /* int y */ /*int z;  之后

就进入了注释段了,在遇到*/之前接下里的行都是注释行。但它本身并不是注释行。

这就说到第1点了,除了这个以下几种情况也都是注释行,如果一行是以//开头,仅有/*两个字符 ,仅有*/两个字符,以/*开头类似这种的/* xx */ /* x xxx */  //xxx,以/*开头类似 /* int x 这种的。

很自然的想到递归计算:

在一行中,前面部分闭合了就不用管了,把后面的子串继续递归。只要遇到上面说的几种情况中的一种就说明是注释行。递归结束还没遇到说明是普通行。

而且在递归中也可以更新flag是否进入了注释段。 两者可以在同一个函数中进行,非常方便。

判断一行本身是否为注释行以及更新/*、*/的函数如下。


bool Counter::judgeAndUpdateComment(string line, bool& flag)  
{
	// /* xxxxxx */ /* x xxx */  //xxxx
	// /*xx */ int x /*
	if(line[0] == '/' && line[1] == '/') return true;
	if(line[0] == '*' && line[1] == '/' && line.length()==2) {flag = false; return true;}
	if(line[0] == '/' && line[1] == '*' && line.length()==2) return flag = true;
	if(line[0] == '/' && line[1] == '*' && line.find("*/")==string::npos) return flag = true;
	string::size_type idx = line.find("/*");
	if(idx != string::npos)   
	{
		flag = true;
	}
	if(flag)
	{
		idx = line.find("*/");
		if(idx != string::npos)
		{
			flag = false;
			line[idx] = line[idx+1] = ' ';
			string sub = line.substr(idx+2,line.length()-idx-2);
			trim(sub);
			if (judgeAndUpdateComment(sub,flag)) return true;
		}
	}
	return false;
}


当然,要配合下面的函数里调用


void Counter::countOneFile(string filepath)
{
	
	ifstream file;
	file.open(filepath,ios::in);
	if (!file.is_open())
	{
		cout << "can't open the file :" << filepath << endl;
		exit(1);
	}
	char buffer[10000];
	bool comment_flag = false;  
	while (!file.eof() )  
    {  
        file.getline(buffer,10000);  
		string line(buffer);
		trim(line);
		if (line.empty())
		{
			m_blank_line++;
		}
		else if(comment_flag)  //如果已经进入了注释段
		{
			m_comment_line++;
			judgeAndUpdateComment(line,comment_flag); //更新 */
		}
		else if (judgeAndUpdateComment(line,comment_flag)) // 本身是注释行
		{
			m_comment_line++;
		}
		else
		{
			m_real_line++;
		}
		
    }  
	cout << "finish: " << filepath << endl;
}
 

这里我没有考虑双引号的影响。双引号里的东西应该忽略的,但是我没有考虑,如果出现类似

string str = "abcd /* "; 的代码,程序得出的结果是灾难性的错误。有需要的同学自己加上。


完整代码 请点击:http://download.csdn.net/download/angon823/10115630





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一套基于C++的Socket TCP通讯代码,并为每一行做好注释: ```c++ #include &lt;iostream&gt; // 包含输入输出流库 #include &lt;cstring&gt; // 包含字符串库 #include &lt;sys/socket.h&gt; // 包含socket网络库 #include &lt;arpa/inet.h&gt; // 包含地址转换库 #include &lt;unistd.h&gt; // 包含UNIX标准库 using namespace std; int main() { int sock = socket(AF_INET, SOCK_STREAM, 0); // 创建一个TCP socket if (sock == -1) { // 如果创建失败 cout &lt;&lt; &quot;Failed to create socket.&quot; &lt;&lt; endl; // 输出错误信息 return -1; } struct sockaddr_in server_addr; // 定义服务器地址结构体 memset(&amp;server_addr, 0, sizeof(server_addr)); // 将结构体清零 server_addr.sin_family = AF_INET; // 指定地址族为IPv4 server_addr.sin_addr.s_addr = inet_addr(&quot;127.0.0.1&quot;); // 设置IP地址 server_addr.sin_port = htons(8888); // 设置端口号 if (connect(sock, (struct sockaddr*)&amp;server_addr, sizeof(server_addr)) == -1) { // 连接服务器 cout &lt;&lt; &quot;Failed to connect to server.&quot; &lt;&lt; endl; // 输出错误信息 close(sock); // 关闭socket return -1; } char msg[] = &quot;Hello, server!&quot;; // 定义消息 if (send(sock, msg, strlen(msg), 0) == -1) { // 发送消息 cout &lt;&lt; &quot;Failed to send message.&quot; &lt;&lt; endl; // 输出错误信息 close(sock); // 关闭socket return -1; } char buffer[1024] = {0}; // 定义接收缓冲区 if (recv(sock, buffer, 1024, 0) == -1) { // 接收服务器回复 cout &lt;&lt; &quot;Failed to receive message.&quot; &lt;&lt; endl; // 输出错误信息 close(sock); // 关闭socket return -1; } cout &lt;&lt; &quot;Received message: &quot; &lt;&lt; buffer &lt;&lt; endl; // 输出接收到的消息 close(sock); // 关闭socket return 0; } ``` 以上是一套基于C++的Socket TCP通讯代码,其中包含了创建socket、连接服务器、发送消息、接收消息和关闭socket等操作。注释中详细说明了每一行代码的作用和含义,希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值