Re: String tokenizer for CString?
This one works pretty well (this may be the same as Giovanni posted:
http://www.codeproject.com/string/ctokenex.asp
I modified it a bunch for specific use and this code may be useful to you.
The credit still goes to the original author since my upgrades were pretty
simple. I needed to be able to split a string that had double quotes and
multiple delimiters.
Tom
// TokenEx.h: interface for the CTokenEx class.
//
//
// MFC Simple CString Tokenizer (Version 1)
//
// Written by Daniel Madden (daniel.madden@compaq.com)
// Copyright (c) 1999
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// Please use and enjoy. Please let me know of any bugs/mods/improvements
// that you have found/implemented and I will fix/incorporate them into this
// file.
//
//
//////////////////////////////////////////////////////////////////////
#pragma once
class CTokenEx
{
public:
CTokenEx();
~CTokenEx();
/*
@FUNCTION: Splits a Path into 4 parts (Directory, Drive, Filename,
Extention).
NOTE: Supports UNC path names.
@PARAM1: Whether the Supplied Path (PARAM2) contains a directory name
only
or a file name (Reason: some directories will end with
"xxx.xxx"
which is like a file name).
@PARAM2: Path to Split.
@PARAM3: (Referenced) Directory.
@PARAM4: (Referenced) Drive.
@PARAM5: (Referenced) Filename.
@PARAM6: (Referenced) Extention.
*/
void SplitPath(BOOL UsingDirsOnly, CString Path, CString& Drive, CString&
Dir, CString& FName, CString& Ext);
/*
@FUNCTION: Splits a CString into an CStringArray according the
Deliminator.
NOTE: Supports UNC path names.
@PARAM1: Source string to be Split.
@PARAM2: Deliminator.
@PARAM3: (Referenced) CStringArray to Add to.
*/
void Split(CString Source, CString Deliminator, CStringArray& AddIt);
int SplitLine(LPCTSTR strLine, LPCTSTR strDelimiters, CStringArray& Array);
/*
@FUNCTION: Joins a CStringArray to create a CString according the
Deliminator.
@PARAM1: Deliminator.
@PARAM2: (Referenced) CStringArray to Add to.
*/
CString Join(CString Deliminator, CStringArray& AddIt);
/*
@FUNCTION: Returns the first string found (according to the token
given). If the
string does not contain a token, then it returns the first
param.
NOTE: This uses a REFERENCE as the first param, so everytime it finds
a token, the string (& deliminator) are removed from the
referenced
string. SEE CODE EXAMPLE!
@PARAM1: (Referenced) csRefered.
@PARAM2: Deliminator.
*/
CString GetString(CString &csRefered, CString Deliminator);
protected:
};
/ TokenEx.cpp: implementation of the CTokenEx class.
//
// MFC Simple CString Tokenizer (Version 1)
//
// Written by Daniel Madden (daniel.madden@compaq.com)
// Copyright (c) 1999
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// Please use and enjoy. Please let me know of any bugs/mods/improvements
// that you have found/implemented and I will fix/incorporate them into this
// file.
//
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TokenEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTokenEx::CTokenEx()
{
}
CTokenEx::~CTokenEx()
{
}
CString CTokenEx::GetString(CString &tmp, CString Search)
{
int nFound;
CString csRet;
CString csTmp1 = tmp;
if (tmp.Left(Search.GetLength()) == Search) {
do {
tmp = csTmp1.Mid(Search.GetLength());
csTmp1 = tmp;
} while (tmp.Left(Search.GetLength()) == Search);
tmp = csTmp1.Mid(Search.GetLength() - 1);
}
CString csTmp = tmp;
nFound = tmp.Find(Search,0);
if (nFound >= 0) {
csRet = csTmp.Left(nFound);
tmp = csTmp.Mid(nFound + (Search.GetLength()));
}
else {
csRet = csTmp;
tmp = _T("");
}
return csRet;
}
CString CTokenEx::Join(CString Deliminator, CStringArray& AddIt)
{
CString csReturn;
CString csTmp;
// Loop through the Array and Append the Deliminator
for( int iNum = 0; iNum < AddIt.GetSize(); iNum++ ) {
csTmp += AddIt.GetAt(iNum);
csTmp += Deliminator;
}
csReturn = csTmp.Left(csTmp.GetLength() - 1);
return csReturn;
}
#define DOUBLE_QUOTE _T('"')
int CTokenEx::SplitLine(LPCTSTR strLine, LPCTSTR strDelimiters,
CStringArray& Array)
{
CString csSource = strLine;
CString csDelimiters = strDelimiters;
TCHAR cDelimiter;
CString csTemp;
int posStart = 0;
int posEnd = 0;
int nTokens = 0;
do {
// If the next character is a double quote it would mean that we need to
scan
// up to the next one before looking for a delimiter.
if(csSource[posStart] == DOUBLE_QUOTE) { // This token starts with quote
posEnd = csSource.Find(DOUBLE_QUOTE,posStart+1); // Find next quote
if(posEnd == -1) { // End of the string
posEnd = csSource.GetLength();
}
else {
// Try all delimiters from list
int i = 0;
int posFound = csSource.GetLength();
while(i < csDelimiters.GetLength()) {
cDelimiter = csDelimiters.GetAt(i++);
int nextPos = csSource.Find(cDelimiter,posEnd);
if(nextPos != -1 && nextPos < posFound)
posFound = nextPos; // We want the very next one that matches
}
posEnd = posFound;
}
}
else {
// Try all delimiters from list
int i = 0;
int posFound = csSource.GetLength();
while(i < csDelimiters.GetLength()) {
cDelimiter = csDelimiters.GetAt(i++);
int nextPos = csSource.Find(cDelimiter,posEnd);
if(nextPos != -1 && nextPos < posFound)
posFound = nextPos; // We want the very next one that matches
}
posEnd = posFound;
}
csTemp = csSource.Mid(posStart,posEnd-posStart);
if(!csTemp.IsEmpty()) {
Array.Add(csTemp);
++nTokens;
}
posStart = posEnd + 1;
posEnd = posStart;
} while (posStart < csSource.GetLength());
return nTokens;
}
void CTokenEx::Split(CString Source, CString Deliminator, CStringArray&
AddIt)
{
CString newCString;
CString tmpCString;
CString AddCString;
// int pos1 = 0;
int pos = 0;
newCString = Source;
do {
pos = newCString.FindOneOf(Deliminator);
if ( pos != -1 ) {
CString AddCString = newCString.Left(pos);
if (!AddCString.IsEmpty())
AddIt.Add(AddCString);
tmpCString = newCString.Mid(pos + Deliminator.GetLength());
newCString = tmpCString;
}
} while ( pos != -1 );
if (!newCString.IsEmpty())
AddIt.Add(newCString);
}
void CTokenEx::SplitPath (BOOL UsingDirsOnly, CString Path, CString& Drive,
CString& Dir, CString& FName, CString& Ext)
{
int nSecond;
// Look for a UNC Name!
if (Path.Left(2) == _T("\\\\")) {
int nFirst = Path.Find(_T("\\"),3);
nSecond = Path.Find(_T("\\"),nFirst + 1);
if (nSecond == -1) {
Drive = Path;
Dir = _T("");
FName = _T("");
Ext = _T("");
}
else if (nSecond > nFirst)
Drive = Path.Left(nSecond);
}
else { // Look for normal Drive Structure
nSecond = 2;
Drive = Path.Left(2);
}
if (UsingDirsOnly) {
Dir = Path.Right((Path.GetLength() - nSecond) - 1);
FName = _T("");
Ext = _T("");
}
else {
int nDirEnd = Path.ReverseFind('\\');
if (nDirEnd == Path.GetLength()) {
Dir = _T("");
FName = _T("");
Ext = _T("");
}
else {
Dir = Path.Mid(nSecond + 1, (nDirEnd - nSecond) - 1);
int nFileEnd = Path.ReverseFind('.');
if (nFileEnd != -1) {
if (nDirEnd > nFileEnd) {
FName = Path.Right(Path.GetLength() - nDirEnd);
Ext = _T("");
}
else {
FName = Path.Mid(nDirEnd + 1, (nFileEnd - nDirEnd) - 1);
Ext = Path.Right((Path.GetLength() - nFileEnd) - 1);
}
}
else {
FName = Path.Right((Path.GetLength() - nDirEnd) - 1);
Ext = _T("");
}
}
}
}
"Weichao Wang" <weichao_wang@hotmail.com> wrote in message
news:B9D4C113-5ACF-44D3-8E9C-844AC9986386@microsoft.com...
Hi all,
is there a string tokenizer for CString in MFC? Thanks for tip!
--
Weichao Wang