MSDN看到的一个读写文件及路径等操作的例子,觉得可以学习一下。。。

// makehm.cpp : A simple utility to create .HM (Help Map) files from
//              .H (resource header files).
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

//  This utility creates a .HM file from a header file (usually
//  resource.h) which allows one to maintain the help mappings
//  without a lot of manual effort on the part of the programmer
//  or help author.
//
//  This is done by naming convention, the naming convention used
//  being that normally accepted as standard Windows and MFC
//  programming practices.

#include <ctype.h>
#include <afxcoll.h>    // also includes <afx.h>

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define SIGNON_VER 10
#define SIGNON_REV 0

/

void UsageErr(const TCHAR* szErrorMessage = NULL,
			  const TCHAR* szErrorParam = NULL)
{
	_ftprintf(stderr,
		_T("\nMicrosoft (R) Help Maintenance Utility   Version %d.%02d\n")
		_T("Copyright (c) Microsoft Corporation.  All rights reserved.\n\n"),
		SIGNON_VER, SIGNON_REV);

	if (szErrorMessage != NULL)
	{
		_ftprintf(stderr, _T("makehm: error: "));
		_ftprintf(stderr, szErrorMessage, szErrorParam);
		_ftprintf(stderr, _T(".\n\n"));
	}

	_ftprintf(stderr, _T("makehm usage:\n\n")
	_T("  makehm [/h [/a <file.h> [/I <path>]]] <from>,<to>,<add>... <resource.h> [output.hm]\n")
	_T("\n")
	_T("    /h     - generates an include file (.h) for HTML help instead of\n")
	_T("             a normal (.hm) WinHelp map file.\n")
	_T("    /a     - copies the contents of the specified <file.h> file to the\n")
	_T("             output.\n")
	_T("    /I     - additional path to search for the file.h file.  The program will\n")
	_T("             first look in the current directory, then the path specified by the\n")
	_T("             /I option and then in the path specified by the INCLUDE\n")
	_T("             environment variable.\n")
	_T("\n")
	_T("    <from>,<to>,<add> fields must appear as one argument and\n")
	_T("       are separated by commas.  A set of these arguments may\n")
	_T("       appear more than once.\n")
	_T("    <from> - identifies the symbol prefix to map from (e.g., ID_)\n")
	_T("    <to>   - identifies the symbol prefix to map to (e.g., HID_)\n")
	_T("    <add>  - identifies a numeric offset to be used (e.g., 0x10000)\n")
	_T("\n")
	_T("    <resource.h> - identifies the input header file (e.g., resource.h).\n")
	_T("    [output.hm] - identifies the output help map file.  If not\n")
	_T("       supplied, output is written to stdout.\n"));

	exit(1);
}

/

class CLineFile : public CStdioFile
{
public:
	BOOL ReadLine(CString& stringLine);
	void WriteLine(const CString& stringLine);
	void SafeOpen(const CString& string, UINT nStyleFlags);
};

BOOL CLineFile::ReadLine(CString& str)
{
	UINT nMax = 512;
	for (;;)
	{
		ULONGLONG pos = GetPosition();
		if (!ReadString(str.GetBuffer(nMax), nMax))
			return FALSE;
		str.ReleaseBuffer();
		if (str.GetLength() < (int)nMax-1)
			return TRUE;
		nMax += 128;
		Seek(pos, CFile::begin);
	}
}

void CLineFile::WriteLine(const CString& str)
{
	ASSERT(str[str.GetLength()-1] == _T('\n'));
	WriteString(str);
}

void CLineFile::SafeOpen(const CString& name, UINT nStyleFlags)
{
	BOOL fSuccess = Open(name, nStyleFlags);
	if (!fSuccess)
		UsageErr(_T("unable to open file \"%s\""), name);
}

/

BOOL IsValidSymbol(const TCHAR* psz)
{
#ifdef UNICODE
	if (!__iswcsymf(*psz))
#else
	if (!__iscsymf(*psz))
#endif
		return FALSE;

	ASSERT(*psz != 0);
	++psz;
	while (*psz)
	{
#ifdef UNICODE
		if (!__iswcsym(*psz))
#else
		if (!__iscsym(*psz))
#endif
			return FALSE;
		++psz;
	}
	return TRUE;
}

//判断是否是8进制
#define isodigit(i) (_T('0') <= (i) && (i) <= _T('7'))

//判断是否是合法值
BOOL IsValidValue(const TCHAR* psz, DWORD& dwValue)
{
	if (*psz == 0 || !_istdigit(*psz))
		return FALSE;

	DWORD dw = 0;
	if (psz[0] == '0' && (psz[1] == 'x' || psz[1] == 'X'))
	{
		if (psz[1] == 0)
			return FALSE;
		psz += 2;
		while (_istxdigit(*psz))
		{
			dw *= 16;
			dw += _istdigit(*psz) ? *psz - '0' : 10 + (*psz|0x20) - 'a';
			++psz;
		}
	}
	else if (psz[0] == '0')
	{
		while (isodigit(*psz))
		{
			dw *= 8;
			dw += *psz - '0';
			++psz;
		}
	}
	else
	{
		while (_istdigit(*psz))
		{
			dw *= 10;
			dw += *psz - '0';
			++psz;
		}
	}

	if (*psz != 0)
		return FALSE;

	dwValue = dw;
	return TRUE;
}

/

CPtrArray aMap;

struct CMapInfo
{
	TCHAR* pszPrefixFrom;
	TCHAR* pszPrefixTo;
	DWORD dwAddTo;
};

void AddToMap(TCHAR* pszArg)
{
	ENSURE(pszArg != NULL);
	TCHAR* psz = _tcsdup(pszArg);
	if (psz == NULL)
	{
		AfxThrowMemoryException();
	}
	ASSERT(_tcschr(psz, _T(',')) != NULL);

	TCHAR* pszPrefixFrom;
	TCHAR* pszPrefixTo;
	TCHAR* pszAddTo;
	DWORD dwAddTo;
	CMapInfo* pInfo;
	TCHAR* pContext=NULL;

	// parse each field out of the argument.
	pszPrefixFrom = _tcstok_s(psz, _T(","), &pContext);
	pszPrefixTo = _tcstok_s(NULL, _T(","), &pContext);
	if (pszPrefixTo == NULL)
		goto ParmError;
	pszAddTo = _tcstok_s(NULL, _T(","), &pContext);
	if (pszAddTo == NULL)
		goto ParmError;

	// make sure they are valid symbols/values.
	if (!IsValidSymbol(pszPrefixFrom) || !IsValidSymbol(pszPrefixTo))
		goto ParmError;
	if (!IsValidValue(pszAddTo, dwAddTo))
		goto ParmError;

	// add them to the map.
	pInfo = new CMapInfo;
	ASSERT(pInfo);
	pInfo->pszPrefixFrom = pszPrefixFrom;
	pInfo->pszPrefixTo = pszPrefixTo;
	pInfo->dwAddTo = dwAddTo;
	aMap.Add(pInfo);
	return;

ParmError:
	UsageErr(_T("parameter \"%s\" not correctly formed."), pszArg);
	ASSERT(FALSE);
}

CMapInfo* FindInMap(const TCHAR* psz)
{
	ENSURE(psz != NULL);
	ENSURE(*psz != 0);
	int nMax = (int)aMap.GetSize();
	for (int i = 0; i < nMax; i++)
	{
		CMapInfo* pInfo = (CMapInfo*)aMap.GetAt(i);
		size_t nLen = _tcslen(pInfo->pszPrefixFrom);
		if (_tcsncmp(pInfo->pszPrefixFrom, psz, nLen) == 0)
			return pInfo;
	}
	return NULL;
}

/

BOOL
MapNameValue(const TCHAR* pszName, CString& strNewName, DWORD& dwValue)
{
	CMapInfo* pInfo = FindInMap(pszName);
	if (pInfo == NULL)
		return FALSE;

	CString strName = pszName;
	strNewName = (CString)pInfo->pszPrefixTo +
		strName.Right(strName.GetLength()-(int)_tcslen(pInfo->pszPrefixFrom));
	dwValue += pInfo->dwAddTo;
	return TRUE;
}

//将UL数字串转化成字符串
CString StringFromDword(DWORD dwValue)
{
	TCHAR buf[sizeof _T("0x12345678")];
	_stprintf_s(buf, sizeof _T("0x12345678"), _T("0x%lX"), dwValue);
	return CString(buf);
}

BOOL MapLine(CString& strLine, BOOL fHTMLFormat )
{
	static TCHAR szWhiteSpace1[] = _T("\t ");
	static TCHAR szWhiteSpace2[] = _T("\t\n ");
	static TCHAR szDefine[] = _T("#define");

	TCHAR* pszCopy = _tcsdup(strLine);
	if (pszCopy == NULL)
	{
		AfxThrowMemoryException();
	}

	TCHAR* psz;
	TCHAR* pszSymbol;
	TCHAR* pszValue;
	DWORD dwValue;
	CString strNewName;
	TCHAR* pContext=NULL;

	// '//{{NOHELP}}' can be placed on the line and it will not be included
	if (_tcsstr(strLine, _T("//{{NOHELP}}")) != NULL)
		goto RetFalse;

	psz = _tcstok_s(pszCopy, szWhiteSpace1, &pContext);
	if (psz == NULL)
		goto RetFalse;
	if (_tcscmp(psz, szDefine) != 0)
		goto RetFalse;
	pszSymbol = _tcstok_s(NULL, szWhiteSpace1, &pContext);
	if (pszSymbol == NULL)
		goto RetFalse;
	pszValue = _tcstok_s(NULL, szWhiteSpace2, &pContext);
	if (pszValue == NULL)
		goto RetFalse;

	if (!IsValidSymbol(pszSymbol))
		goto RetFalse;
	if (!IsValidValue(pszValue, dwValue))
		goto RetFalse;
	if (!MapNameValue(pszSymbol, strNewName, dwValue))
		goto RetFalse;

	//BLOCK: format output line
	{
		CString strPad(_T(' '), 40-strNewName.GetLength());
		if (strPad.IsEmpty())
			strPad = _T('\t');
		if( fHTMLFormat )
			strLine = _T("#define ") + strNewName + strPad + StringFromDword(dwValue) + _T("\n");
		else
			strLine = strNewName + strPad + StringFromDword(dwValue) + _T("\n");
	}

	ASSERT(pszCopy != NULL);
	free(pszCopy);
	return TRUE;

RetFalse:
	ASSERT(pszCopy != NULL);
	free(pszCopy);
	return FALSE;
}

void AddPath( CStringList& strrgPathList, const CString& strIncludePath )
{
	CString strPath;
	int curPos = 0;

	strPath = strIncludePath.Tokenize(_T(";"), curPos );

	while( ! strPath.IsEmpty() )
	{
		strPath.TrimLeft();
		strPath.TrimRight();
		strrgPathList.AddTail( strPath );
		strPath = strIncludePath.Tokenize(_T(";"), curPos );
	}
}

//判断文件是否存在
BOOL FileExists( const TCHAR *pszFileName )
{
	BOOL r = FALSE;
	CStdioFile file;
	if( file.Open( pszFileName, CLineFile::modeRead ) )
	{
		file.Close();
		r = TRUE;
	}

	return r;
}

CString FindIncludeFile( const TCHAR *pszIncludeFilename, const TCHAR *pszIncludePath )
{
	CString strEnvInclude;
	CStringList strrgPathList;
	
	if( FileExists( pszIncludeFilename ) )
		return CString(pszIncludeFilename);
	
	// add current directory to path list;
	strrgPathList.AddTail( ".\\" );
	
	// add path specified in the command line (/I option)
	if( pszIncludePath )
		AddPath( strrgPathList, pszIncludePath );
	
	// add path specified in the INCLUDE variable
	if( strEnvInclude.GetEnvironmentVariable( _T("INCLUDE") ) )
		AddPath( strrgPathList, strEnvInclude );
	
	POSITION pos = strrgPathList.GetHeadPosition();
	for (int i=0;i < strrgPathList.GetCount();i++)
	{
		CString strPath = strrgPathList.GetNext(pos);
		CString tmp = strPath.Right(1);
		if( tmp != ":" && tmp != "\\" )
			strPath += '\\';
		
		strPath += pszIncludeFilename;
		
		if( FileExists( strPath ) )
			return CString(strPath);
	}

	return CString("");
}

/

int _tmain(int argc, TCHAR** argv)
{
	int iFirstParam = 1;

	// Turn on the "termination on heap corruption" flag.
	(void)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);

	// generate output for HTML Help format
	BOOL fHTMLFormat = FALSE;

	// <include.h> filename to be copied
	const TCHAR *pszIncludeFilename = NULL;

	// additional include path
	const TCHAR *pszIncludePath = NULL;

	if( argc > 1 && _tcsicmp(argv[1], _T("/h")) == 0 )
	{
		fHTMLFormat = TRUE;
		iFirstParam++;

		if( ( argc > 3 ) && _tcsicmp(argv[2], _T("/a")) == 0 ) // copy file operation
		{
			pszIncludeFilename = argv[3];
			iFirstParam += 2;

			if( argc > 5 && _tcsicmp(argv[4], _T("/i")) == 0 )
			{
				pszIncludePath = argv[5];
				iFirstParam += 2;
			}
		}
	}

	// add symbol mappings to the map.
	BOOL fAddedToMap = FALSE;
	int i;
	for (i = iFirstParam; i < argc && _tcschr(argv[i], _T(',')) != NULL; i++)
	{
		AddToMap(argv[i]);
		fAddedToMap = TRUE;
	}

	// must only have 1-2 parms left on command line.
	if (!fAddedToMap || i < argc-2 || i > argc-1)
	{
		UsageErr(NULL, NULL);
		ASSERT(FALSE);
	}

	// open input file.
	CLineFile fileIn;
	fileIn.SafeOpen(argv[i], CLineFile::modeRead);

	// open/hook up output file.
	CLineFile fileOut;
	if (i+1 < argc)
		fileOut.SafeOpen(argv[i+1], CLineFile::modeWrite | CLineFile::modeCreate);
	else
		fileOut.m_pStream = stdout;

	// process the file.
	CString strLine;
	while (fileIn.ReadLine(strLine))
	{
		if (MapLine(strLine, fHTMLFormat))
		{
			fileOut.WriteLine(strLine);
		}
	}

	// close input file.
	fileIn.Close();

	if( pszIncludeFilename != NULL )
	{
		CString strIncludeFilePath = FindIncludeFile( pszIncludeFilename, pszIncludePath );
		if( strIncludeFilePath.IsEmpty() )
		{
			_ftprintf(stderr, _T("Error: Additional include file %s not found\n\n"), pszIncludeFilename );
			fileOut.Close();
			exit(1);
		}

		fileIn.SafeOpen(strIncludeFilePath, CLineFile::modeRead);

		while (fileIn.ReadLine(strLine))
		{
			fileOut.WriteLine(strLine);
		}
	}

	// close output file.
	fileOut.Close();

	return 0;
}

/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值