将一个目录下所有指定文件里面的特定字符串替换

           想把自己以前完成的一个工程里面特定字符串替换,本来用脚本是很简单的,但是自己还不会只得用VC写了一个程序,蛋疼啊。

程序涉及到知识点: 指针 链表  文件遍历  内存映射文件

代码如下:

 

// Test2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"

#define MAC_FILENAMELENOPATH 50

typedef	struct	Node {
		Node	*next;
		char	Name[256];
}Node;


void	FindFileInDir(char* rootDir);
void	AddToChain(Node *pTempNode);
void	FreeMem(void );
bool	IsFile(char *Name);
void	HandleFile(char *Name);
void	Temp();

char		SouceString[256],DestString[256];
char		* strPath = "f:\\WorkPlace\\005";			///工程所在的目录
Node		*Head,*Tail;


char	*src[] ={"abcdef",NULL };				///源字符串
char	*dest[]={"GDEGEF",NULL};				///要替换成的字符串


int main(/*int argc, char *argv[]*/)
{
	int	i,j;

	for (i = 0;src[i];i ++)
	{
		strcpy(SouceString,src[i]);
		strcpy(DestString ,dest[i]);

		Temp();
	}
	return 0;
}

void	Temp()
{
	Node	*pTemp;
	Head	= Tail	= NULL;

	FindFileInDir(strPath);				/// 此函数执行完时, Head Tail 链表里面已经有了存储内容。

	pTemp	= Head;

	while(1)
	{
		if(pTemp == NULL)
		{
			break;
		}
		if(IsFile(pTemp->Name))
		{
			HandleFile(pTemp->Name);
		}
		pTemp	= pTemp->next ;
	}

	FreeMem();
}

void FindFileInDir(char* rootDir)
{
	char	fname[MAC_FILENAMELENOPATH];	
	ZeroMemory(fname, MAC_FILENAMELENOPATH);

	WIN32_FIND_DATA fd;
	ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));

	HANDLE hSearch;
	char filePathName[256];
	char tmpPath[256];

	ZeroMemory(filePathName, 256);
	ZeroMemory(tmpPath, 256);

	Node	*pTempNode;

	strcpy(filePathName, rootDir);

	BOOL bSearchFinished = FALSE;

	if( filePathName[strlen(filePathName) -1] != '\\' )
	{
		strcat(filePathName, "\\");
	}

	strcat(filePathName, "*");

	hSearch = FindFirstFile(filePathName, &fd);

	//Is directory
	if( (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		&& strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )		
	{
		strcpy(tmpPath, rootDir);
		strcat(tmpPath,"\\");
		strcat(tmpPath, fd.cFileName);
		FindFileInDir(tmpPath);
	}
	
	else	if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
	{
		pTempNode	= (Node *)VirtualAlloc(NULL, /// 分配内存区域的地址。当你使用VirtualAlloc来提交一块以前保留的内存块的时候,
						  //lpAddress参数可以用来识别以前保留的内存块。
						  ///如果这个参数是NULL,系统将会决定分配内存区域的位置,并且按64-KB向上取整(roundup)。 
						//内存保留提交映射 三部曲(windows核心编程)
				sizeof(Node),	//要分配或者保留的区域的大小。这个参数以字节为单位,而不是页,
						//系统会根据这个大小一直分配到下页的边界DWORD 
				MEM_COMMIT,	//分配指定 保留 的内存页
				PAGE_READWRITE);      
		strcpy(pTempNode->Name ,rootDir);
		strcat(pTempNode->Name ,"\\");
		strcat(pTempNode->Name ,fd.cFileName );
		pTempNode->next		= NULL;
		AddToChain(pTempNode);
	}

	while( !bSearchFinished )
	{
		if( FindNextFile(hSearch, &fd) )
		{
			//Is directory
			if( (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				&& strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )		
			{
				strcpy(tmpPath, rootDir);
				strcat(tmpPath,"\\");
				strcat(tmpPath, fd.cFileName);
				FindFileInDir(tmpPath);
			}	
			else if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
			{
				pTempNode	= (Node *)VirtualAlloc(NULL, sizeof(Node),  MEM_COMMIT, PAGE_READWRITE);      
				strcpy(pTempNode->Name ,rootDir);
				strcat(pTempNode->Name ,"\\");
				strcat(pTempNode->Name ,fd.cFileName );
				pTempNode->next		= NULL;
				AddToChain(pTempNode);
			}
		}
		else
		{
			if( GetLastError() == ERROR_NO_MORE_FILES )			//Normal Finished
			{
				bSearchFinished = TRUE;
			}
			else
				bSearchFinished = TRUE;		//Terminate Search
		}
	}
	FindClose(hSearch);
}

///将一个节点增加到 链表上。
void	AddToChain(Node *pNode)
{
	if(Head == NULL )
	{
		Head	= Tail	= pNode;
	}
	else
	{
		Tail->next	= pNode;
		Tail		= pNode;
	}
}

///释放链表中内存
void	FreeMem(void )
{
	Node	*pTemp;
	if(Head	== NULL)
		return ;
	pTemp	= Head->next ;
	while(1)
	{
		VirtualFree(Head,sizeof(Node),MEM_DECOMMIT);
		Head	= pTemp;
		pTemp	= Head->next ;
		if(pTemp == NULL)
		{
			break;
		}
	}
}

///判断是否是指定的文件 .c 或者 .h。
bool	IsFile(char *Name)
{
	char	*pTemp;

	pTemp	= Name + strlen(Name);
	while(*pTemp != '\\')
	{
		pTemp --;
	}

	pTemp	= strstr(Name,".");
	if(pTemp == NULL)
	{
		return FALSE;
	}
	if( (strcmp(pTemp,".c") == 0)	||
		(strcmp(pTemp,".h") == 0)	)
	{
		return TRUE;	
	}
	return FALSE;
}

///对于指定的文件打开,替换字符串
///对于替换字符串有一个规律:
///DestString长度要比SouceString要短。
void	HandleFile(char *Name)
{
	HANDLE		hFile;
	LPTSTR		hMap;
	LPTSTR		lpMapAddr;
	char		*pTemp;
	char		*pStr;
	int			Len,LenDest;
	int			i;

	hFile		= CreateFile(Name,						
					GENERIC_READ |GENERIC_WRITE ,			// 表示允许对设备进行读写访问;(组合)
					0,										//dwShareMode Long,零表示不共享; FILE_SHARE_READ/WRITE 表示允许对文件进行共享访问 
					NULL,									//指向一个SECURITY_ATTRIBUTES结构的指针,定义了文件的安全特性
					OPEN_EXISTING ,							//OPEN_EXISTING 文件必须已经存在。由设备提出要求 
					FILE_ATTRIBUTE_NORMAL,					//dwFlagsAndAttributes Long,FILE_ATTRIBUTE_NORMAL 默认属性 
					0 );									//hTemplateFile Long,如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性
	hMap		= (LPTSTR)CreateFileMapping(hFile,			// 一个文件句柄
					NULL,									//定义内存映射文件对象是否可以被承
					PAGE_READWRITE,							//该内存映射文件的保护类型
					0,										// 内存映射文件的长度 高位
					GetFileSize(hFile, NULL),				// 内存映射文件的长度 低位
					"MyMap");								// 内存映射文件的名字
	lpMapAddr	= (LPTSTR)MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS, 0,0,0);
    
	Len			= strlen(SouceString);
	LenDest		= strlen(DestString);

	pStr		= (char *)lpMapAddr;
	i			= 0;

	while(1)
	{
		pTemp	= strstr((char *)pStr,SouceString);
		if(pTemp == NULL)
			break;
		memset(pTemp,9,Len);								// IDE 集成环境里面 空格字符ASCII码是 9
		for(i=0;i < LenDest;i ++)
		{
			*pTemp	++ = DestString[i];
		}
		pStr	= pTemp + Len;
	}

	UnmapViewOfFile(lpMapAddr);
	CloseHandle(hMap);
	CloseHandle(hFile);
}


 

            

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值