计算文件的行数.

这里参考了  代码行数统计(修复版)  http://download.csdn.net/detail/jokers_i/4939098 ,  但有一点小bug.. 这里修正了再贴出来.作为自己学习笔记..  感谢原作者..

 

这里建立控制台演示下代码.

代码如下:

#include <iostream>
#include <Winsock2.h>	// for 
#include <Windows.h>  
#include <string>  
using namespace std;

#pragma comment(lib, "Ws2_32.lib")


struct CodeFileLineInfo{
	DWORD codeline;
	DWORD blankline;
	LPTSTR filename;
	CodeFileLineInfo():codeline(0),blankline(0),filename(NULL){}
	VOID Reset(){codeline=blankline=0;}
}; 


CONST WORD Utf_8_header = 0xBBEF;
CONST WORD Uc_littte_header = 0xFEFF;
CONST WORD Uc_big_header = 0xFFFE;

inline BOOL IsVisibleChar(WORD c)
{
	CONST WORD uvc[]={' ','\r','\n','\t'};
	for (DWORD i=0;i<sizeof(uvc)/sizeof(uvc[0]);i++)
	{
		if (c==uvc[i])
		{
			return FALSE;
		}
	}
	return TRUE;
}



template<class T>
VOID CalcLines(CONST T* buffer,CONST T seprator,CONST DWORD nchars,CodeFileLineInfo& cfi)
{  
	DWORD visible = 0;
	for (DWORD i = 0;i<nchars;i++)
	{
		visible += IsVisibleChar(buffer[i]);
		if (buffer[i] == seprator)
		{
			if (visible==0)
			{
				++cfi.blankline;
			}
			else
			{
				++cfi.codeline;
			}
			visible = 0;
		}
	}


	if (buffer[nchars-1]!=seprator)
	{
		++cfi.codeline;
	}
	else if (buffer[nchars - 1] == T(10))  // 加入这个判断,如果最后一行是空行的话.也应该计算进去
	{
		++cfi.blankline;
	}
}	


VOID NumbericCodeLine(LPCTSTR filePath, CodeFileLineInfo& codeFileInfo)
{  
	HANDLE codefile = CreateFile(filePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if (codefile==INVALID_HANDLE_VALUE)
	{
		//AfxMessageBox(_T("打开文件失败"));
		return;
	}
	BY_HANDLE_FILE_INFORMATION bhfif;
	GetFileInformationByHandle(codefile,&bhfif);

	if (bhfif.nFileSizeLow==0)	// 这里只判断文件大小的低位的是否为0,因为高位的不为0,也是文件相当大的了 --- benben 补注
	{
		return;
	}  

	LPVOID buffer=VirtualAlloc(NULL,bhfif.nFileSizeLow,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
	if (!buffer)
	{
	//	AfxMessageBox(_T("alloc memory failed!"));
		return;
	}
	ReadFile(codefile,buffer,bhfif.nFileSizeLow,&bhfif.nFileSizeHigh,NULL);
	CloseHandle(codefile);
							 

	WCHAR * wcBuffer = (WCHAR *)buffer;
	DWORD nchars = 0;


	if (wcBuffer[0]==Uc_littte_header||wcBuffer[0]==Uc_big_header)
	{
		nchars = (bhfif.nFileSizeLow-2)/2;
		//处理Unicode with littel or big endian file
		WCHAR NEWLINE=0x000A;
		if (wcBuffer[0]==Uc_big_header)
		{
			for (DWORD i=0;i<nchars+1;i++)
			{
				wcBuffer[i] = ntohs(wcBuffer[i]);
			}
		}
		//skip the header word
		wcBuffer = wcBuffer+1;
		CalcLines(wcBuffer,NEWLINE,nchars,codeFileInfo);
	} 
	else if (wcBuffer[0]==Utf_8_header)
	{
		//Utf-8 encode file
		CalcLines((CHAR*)buffer+3,'\n',bhfif.nFileSizeLow-3,codeFileInfo);
	}
	else
	{
		//ANSI encode file
		CalcLines((CHAR*)buffer,'\n',bhfif.nFileSizeLow,codeFileInfo);
	}
	VirtualFree(buffer,bhfif.nFileSizeLow,MEM_RELEASE);
}  


int main()
{
	CodeFileLineInfo LineInfo;

	std::string fileName("c:\\test\\console_study.cpp");
   NumbericCodeLine(fileName.c_str(), LineInfo); 


   cout << fileName.c_str() << endl;
   cout << "NonBlankLine = " << LineInfo.codeline << endl;
   cout << "BlankLine = " << LineInfo.blankline << endl;
   cout << "总行数: " << (LineInfo.codeline + LineInfo.blankline) << endl;	  

	return 0;	
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值