Click here to Skip to main content
Licence 
First Posted 10 Mar 2003
Views 74,175
Bookmarked 14 times

Fast splitting of CString objects

By | 23 Sep 2005 | Article
Splitting CString objects is mostly easy, but can be tricky. I developed this function for using it with CSV files.

Introduction

Splitting CString objects is mostly easy. But in some special cases, like handling CSV data, the following function can do a good job: it explains how to handle strings that contain the separator itself in the text.

The solution is to 'escape' all separators that occur in the text itself and use a splitting function that is aware of this 'escape' (chMagic) character. The following function extends AfxGetSubString with this behaviour and is optimized to be as fast as possible while using CString.

The extracted CString substring is directly manipulated using the GetBufferSetLength member function.

Code

// Get substring, chMagic is a character which 
// makes chSep act as a normal character. 
// Return TRUE on success. 
inline BOOL GetSubString(CString& strSub, LPCTSTR lpszFullString, 
                         int iFullStringLen, int iSubString, TCHAR chSep, 
                         TCHAR chMagic) 
{ 
    int iPos, iPosOrig, iStartPos, iEndPos, iNumMagics; 
    TCHAR* pcSubString; 
    if((lpszFullString == NULL) || 
        (iFullStringLen == 0)) 
        return FALSE; 
    // Find substring begin 
    for(iStartPos = 0; (iStartPos < iFullStringLen) && (iSubString > 0); 
        iStartPos++) 
    { 
        // May be separator ? 
        if(*(lpszFullString + iStartPos) == chSep) 
        { 
            if(((iStartPos > 0) && 
                (*(lpszFullString + iStartPos - 1) != chMagic)) 
                || (iStartPos == 0)) 
            { 
                // Sure it is a separator! 
                iSubString--; 
            } 
        } 
    } 

    // Return empty string when nothing found 
    if(iSubString > 0) 
    { 
        strSub.Empty(); 
        return FALSE; 
    } 

    // Find substring end 
    iNumMagics = 0; 
    for(iEndPos = iStartPos; 
        iEndPos < iFullStringLen; 
        iEndPos++) 
    { 
        // Count magics 
        if(*(lpszFullString + iEndPos) == chMagic) 
        { 
            iNumMagics++; 
        } 
        // May be separator ? 
        if(*(lpszFullString + iEndPos) == chSep) 
        { 
            if(((iEndPos > 0) && (*(lpszFullString + iEndPos - 1) 
                != chMagic)) || (iEndPos == 0)) 
            { 
                // Sure it is the end 
                break; 
            } 
        } 
    } 

    // Copy substring 
    pcSubString = strSub.GetBufferSetLength(
        iEndPos - iStartPos - iNumMagics); 
    iPosOrig = iStartPos; 
    iEndPos -= iStartPos; 
    if(pcSubString != NULL) 
    { 
        for(iPos = 0; iPos < iEndPos; iPos += sizeof(TCHAR)) 
        { 
            if(*(lpszFullString + iPosOrig) != chMagic) 
            { 
                *(pcSubString + iPos) = *(lpszFullString + iPosOrig); 
            } 
            else 
            { 
                iPos -= sizeof(TCHAR); 
                iEndPos -= sizeof(TCHAR); 
            } 
            iPosOrig += sizeof(TCHAR); 
        } 
        *(pcSubString + iPos) = 0; 
        return TRUE; 
    } 
    return FALSE; 
};

Example

CString strSub, strLine("1,2,3\\,1,4,..."); 
int iLen = strLine.GetLength(); 
GetSubString(strSub, strLine, iLen, 0, ',', '\\'); // strSub: 1 
GetSubString(strSub, strLine, iLen, 1, ',', '\\'); // strSub: 2 
GetSubString(strSub, strLine, iLen, 2, ',', '\\'); // strSub: 3,1

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

rkaufman

Web Developer

Switzerland Switzerland

Member

Working as software developer in communication and automotive industry.
To contact me: softwaredeveloper [at ]dieselschrauber.de
Visit my Website to view my current work.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralCode Pinmembercarlmalden4:54 14 Aug '07  
GeneralBugs found Pinsussrusselo17:47 6 May '03  
GeneralThis is no bug Pinmemberrkaufman4:02 7 May '03  
GeneralAnother option PinmemberBill Oliver3:43 29 Apr '03  
Generaltry this instead.. PinmemberBill Gates Antimatter Particle21:56 11 Mar '03  
GeneralRe: try this instead.. Pinmemberrkaufman4:55 12 Mar '03  
QuestionWhat's about AfxExtractSubString? PinmemberHolger Persch19:47 11 Mar '03  
AnswerRe: What's about AfxExtractSubString? Pinmemberrkaufman4:57 12 Mar '03  
GeneralRe: What's about AfxExtractSubString? PinmemberMichael D. Borghardt10:11 7 Oct '04  
GeneralRe: What's about AfxExtractSubString? PinmemberMichael D. Borghardt10:11 7 Oct '04  
GeneralRe: Observations Pinmemberrkaufman5:11 12 Mar '03  
Generaldefine fast... PinsussAnonymous5:45 11 Mar '03  
GeneralRe: define fast... Pinmemberrkaufman5:00 12 Mar '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 23 Sep 2005
Article Copyright 2003 by rkaufman
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid