`

去除C/C++中的注释

阅读更多
/********************************************************
	功能:去除C/C++中的注释
	输入:指向C/C++程序代码的指针
	来源:程序员面试宝典第45页
	注意:①要考虑到""或' '中的//和/*,//和/*的嵌套关系。
		  ②单引号、双引号中的//是两个字符,第一个字符在单引号的case语句中跳过了,
		  第二个字符则在case '/'中处理。
 *********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

void remove_comment(char *buf, size_t size)
{
	char *p, *end, c;          //p-动态移动的字符指针,end-指向文件末尾的字符指针,c-存储没一个p指向的字符
	char *sq_start, *dq_start; //sq_start-单引号开始位置(single),dq_start-双引号开始(double)
	char *lc_start, *bc_start; //lc_start-//的开始位置,bc_start-/*的开始位置
	size_t len;                //记录某符号结束和开始的位置之差(长度,偏移量)
	
	p = buf;
	end = p + size;
	sq_start = dq_start = NULL;
	lc_start = bc_start = NULL;
	
	while (p < end) /*当指针没有到达文件末尾   \r///***///*/,故意带这些不规范的符号的,因为调试就用这个代码,哈哈。*/
	{
		c = *p;     //用字符变量c存储指针指向的字符
		
		switch (c) //根据c的值做相应处理
		{
			case '\'': /*处理单引号,其实只是为了排除'//'的情况,否则不需要有这个情况判断*/
			{
				if (dq_start || lc_start || bc_start) //当遇到过双引号、//或/*的时候,则不需要再判断'//'的情况了。
				{
					p++;
					continue; //继续下一个,对while而言的
				}
				/*******************************以下是没有遇到过双引号或//或/*的时候*******************************/
				if (sq_start == NULL) /****否则:如果未遇到单引号****/
				{
					sq_start = p++; //start指向单引号的开始位置,p指向下一个(分两句理解)
				}
				else /*如果遇到过单引号,sq_start指向单引号开始位置*/
				{
					len = (p++) -sq_start; //len = p-sq_start; p++;
					if (len == 2 && *(sq_start+1) == '\\') //这个是将遇到'//'的情况排除
					{
						continue; //忽略单引号中单独存在//的时候,即不再往下处理。
					}
					
					sq_start = NULL; //否则将sq_start置位为NULL,C语言中单引号内最多只可能有一个字符而已,不要思考复杂了哦len == 0 或 1 或 2
				}
				/*******************************以上是没有遇到过双引号或//或/*的时候*******************************/
				break;
			}
			
			case '\"': /*处理双引号,其实只也是为了排除"//"的情况,否则不需要有这个情况判断,注意第二个斜杠不在这里判断*/
			{
				if (sq_start || lc_start || bc_start) //当遇到过单引号、//或/*的时候,则不需要处理
				{
					p++;
					continue;
				}
				/*****************以下是没有遇到过单引号或//或/*的时候*****************/
				if (dq_start == NULL) /*如果没有遇到过双引号*/
				{
					dq_start = p++; //标记遇到了双引号
				}
				else if (*((p++) -1) =='\\') //双引号中的/也不需要处理。
				{
					continue;
				}
				printf("hello // world?? /**/"); //这种情况呢?怎么办?——这个情况会在遇到/是的第一个if语句被跳过
				
				
				dq_start = NULL; //如果双引号中不是//,标记为NULL
				/*****************以上是没有遇到过单引号或//或/*的时候*****************/
			}
			
			case '/': //斜杠,注意这个斜杠也可以是'//',"//",//,/*/中的第二个斜杠,但会在下面第二行代码中被忽略掉
			{
				if (sq_start || dq_start || lc_start || bc_start) //如果是单引号、双引号、斜杠、/*的后面
				{
					p++;
					continue;
				}
				/***********************下面是遇到注释//或/*的时候****************************/
				c = *(p + 1); //否则c取p指向字符的下一个字符
				if (c == '/') //遇到了双斜杠
				{
					lc_start = p; //标记双斜杠的开始
					p += 2; //p指向双斜杠后面的字符
				}
				else if (c == '*') //遇到了/*
				{
					bc_start = p; //标记/*的开始
					p += 2; //p指向/*后面的字符
				}
				/*************************上面是遇到注释//或/*的时候**************************/
				else
				{ //其它情况,再去判断下一个是什么符号——注意:C程序可以有其他情况吗?这句话我认为永远不可能执行到。
					p++; 
				}
			}
			
			case '*': //星号,同斜杠,但少了如果遇到/*的情况,因为遇到这种情况后,要判断是不是遇到结束的地方*/了
			{
				if (sq_start || dq_start || lc_start) //如果是单引号、双引号、斜杠、/*的后面
				{
					p++;
					continue; 
				}
				
				if (*(p + 1) != '/') //如果星号后面紧跟的不是斜杠,那么忽略过。
				{
					p++;
					continue;
				}
				
				p += 2; //否则p指向斜杠后面那个字符。注意下面的清空语句,p指向的那个字符并不会被清除。
				memset(bc_start, ' ', p-bc_start); //清空/* …… */中间的内容包括注释符号本身。
				bc_start = NULL;
				break;
			}
			
			case '\n': /*换行符,主要处理遇到双斜杠时,需要清除双斜杠到\n的前面的字符*/
			{
				if (lc_start == NULL) //如果还没有遇到双斜杠,那么忽略
				{
					p++;
					continue; /*这两行本程序每次case后面都紧跟,就是忽略过的意思*/
				}
				
				c = *(p - 1);
				//如果遇到过双斜杠,清空双斜杠本身和到n前面的那个字符,p指向下一个字符,/r是回车符(光标退回到最前面),要忽略。有这个情况吗???
				memset(lc_start, ' ', (c == '\r'? ((p++) -1) : p++) - lc_start); 
				lc_start = NULL;
				break;
			}
			
			default:
				p++;
				break;
		}
		/****************************************************
		如果遇到双斜杠,这个if语句存在的意义在于万一最后
		一行代码是带有双斜杠但没有给换行符\n的,也要清除掉。
		不带文件末尾的双斜杠的行尾一定有\n,这不是代码中写的
		\n而是我们的回车键换行操作写入文件的。
		*****************************************************/
		if (lc_start) 
		{
			memset(lc_start, ' ', p - lc_start);
		}
	}
}

/**********************************************
			main函数的开始
***********************************************/
int main (int argc, char *argv[])
{
	int fd, n;
	char buf[102400];
	
	if (argc != 2)
	{
		printf("command error: Input as ./command <file>\n");
	}
	
	fd = open(argv[1], O_RDONLY); /*只读打开*/
	if (fd == -1)
	{
		return -1;
	}
	
	n = read(fd, buf, sizeof(buf));
	if (n == -1 || n == 0)
	{
		close(fd);
		return -1;
	}
	printf("test\n");
	remove_comment(buf, n);
	*(buf + n) = '\0';
	printf("%s", buf);
	close(fd);
	
	return 0;
}


0
0
分享到:
评论

相关推荐

    C/C++源程序去注释工具

    标题 "C/C++源程序去注释工具" 暗示了这个压缩包包含一个用于删除C或C++源代码中的注释的程序。这样的工具在特定情况下可能会有用,例如在进行代码分析、保密处理或者简化代码阅读时。C/C++编程语言允许开发者通过...

    C/C++代码注释自动删除工具(源代码)

    C/C++代码注释自动删除工具,工程编译之后生成的exe文件,文件执行之后会自动扫描文件所在目录以及子目录中的所有c、cpp、h、inl文件中的注释,并处理注释删除之后造成的空格或者空行,并将原始文件备份成tmp文件。...

    简易C++/C注释去除工具

    一个简易的C++/C注释去除工具. 支持批量文件去除.

    批量删除C和C++注释

    总之,使用Python进行批量删除C/C++注释是一个高效且实用的方法,它依赖于正则表达式的强大匹配能力。通过理解代码的逻辑,你可以根据自己的需求调整代码,实现更复杂的注释处理任务。在进行此类操作时,确保对源...

    C/C++源程序注释的删除

    C语言注释删除程序 [程序功能] 1、删除注释,包括块注释(/**/)和行注释(//) 2、删除空白行 3、用指定数量的空格替换TAB字符 [使用方法] 1、在WINDOWS的CMD窗口中键入行命令 2、使用WINDOWS的批处理文件(.BAT...

    清除C/C++空行、注释

    在软件开发过程中,尤其是涉及到版权保护和源码管理时,可能会有需求清除C或C++源代码中的空行和注释。这样的操作有助于减少代码体积,保护源码隐私,同时在统计代码行数时,可以更准确地反映出实际编写的有效代码量...

    C/C++/Java 源代码注释清除工具

    为了适应这些情况,一种专门用于清除C、C++和Java源代码中注释的工具应运而生。本文将深入探讨这款工具的设计初衷、功能特点、操作便利性以及它在软件开发中的实际应用价值。 首先,这款“C/C++/Java 源代码注释...

    把C/C++中的注释去掉

    5_8_5 5_8_5.cpp old file: 5_8_5.cpp ==&gt; new file 5_8_5.cpp_ _8_5 -h -h: read help information. -k: keep line as before.

    去除C++源文件注释

    另一个文件是RemoveComments.exe,这很可能是一个执行去除C++注释功能的可执行程序。它可能采用了上述的解析方法,读取源代码文件,识别并移除注释,然后输出处理后的源代码。使用这样的工具可以方便快捷地批量处理...

    使用Python语言 ,实现批量删除C/C++类型注释

    批量删除C和C++注释 1.目前支持去掉.h .hpp .c .cpp .java 这些以//或/**/为注释符的源文件 2.支持递归遍历目录 3.当前版本为Python2.7版本,故只有安装了Python2.7(或Python3.x以下版本的才可以直接使用,测试...

    清除c/c++代码中条件编译部分的程序,帮助阅读源代码,生成好的tags

    网上众多的开源C/C++代码,因为跨平台的需要,参杂了许多的条件编译语句,对阅读源代码造成了不方便,而且用ctags等工具生成源代码的tags文件时会有些妨碍,本工具就是用来预处理这些条件编译的,将未定义的区域自动...

    从 C/C++ 代码中删除注释:从 C/C++ 源文件中删除注释。 不做任何预处理。-matlab开发

    在C/C++编程中,注释是用于解释代码功能、逻辑或提高代码可读性的文本。它们对于人类阅读代码非常有帮助,但在某些特定情况下,比如编译优化或代码分析时,可能需要去除这些注释。标题提到的是一个关于如何在不进行...

    C++删除注释小工具

    支持c++的注释格式,删除单个文件时没有文件名称限制,当采用文件夹模式时,会在该文件夹及其子文件夹中搜索所有*.cpp, *.c, *h文件并删除源码中的注释。操作过程中会自动备份原文件。 时间仓促,可能还有一些问题,...

    去除注释 去注释

    本篇文章将详细探讨如何去除C++代码中的单行注释(//注释)和多行注释(/**/注释),以及可能涉及到的相关技术。 首先,我们要理解C++中的注释结构。单行注释以`//`开始,直到行尾结束;而多行注释则以`/*`开始,`*...

    原程序注释

    给定 C/C++ 源程序的源代码,要求去掉所有的注释代码并输出去除注释后的代码。已知 C/C++ 代码的注释有两种:单行注释和多行注释,前者稳以“ // ”引导的行;后者则是由“ /* ”和“ */ ”包含的部分,可以在同一...

    DES加密解密C/C++接口

    在C/C++中实现DES加密解密接口,你需要理解以下核心概念: 1. 密钥扩展:DES的56位密钥需要通过一系列的Permutation和Combining操作扩展成64位,去除每轮使用的8位奇偶校验位,实际用于加密的密钥是56位。 2. ...

    c/c++词法分析预处理

    c/c++词法分析预处理cpp源代码,将同目录下"abc.cpp"去除跳格回车换行注释和不必要的空格,输出文件"abc_chuli.cpp",因为具体要求不同,这处理出来的文件还是能继续编译运行。

    c/c++面试资料大全

    - 对于C/C++面试,重点应放在掌握语言基础、数据结构、算法、内存管理、指针操作、面向对象编程(C++中)等方面。 - 实际问题解决能力很重要,如上述题目所示,理解题意、调试代码和优化算法都是面试中常见的考核...

    Qt编写移除C++代码注释源码

    在C++代码中,注释主要有两种形式:单行注释(//)和多行注释(/* ... */)。这个项目的目标就是识别并移除这两种类型的注释,同时保持原始代码的结构和功能不变。 实现这个功能的关键在于理解C++的语法规则,尤其...

    去掉代码注释的工具java \ c\c++、php等

    然而,在某些情况下,比如代码分析、编译优化或版本控制时,我们可能需要去掉这些注释以减少不必要的信息。针对这种情况,出现了专门去除代码注释的工具。本文将详细介绍如何使用这些工具,主要涉及Java、C/C++和PHP...

Global site tag (gtag.js) - Google Analytics