478 Stimmen

Wie kann ich eine Zeichenkette in C++ tokenisieren?

Java verfügt über eine praktische Split-Methode:

String str = "The quick brown fox";
String[] results = str.split(" ");

Gibt es eine einfache Möglichkeit, dies in C++ zu tun?

234 Stimmen

Ich kann nicht glauben, dass diese Routineaufgabe in C++ so viel Kopfzerbrechen macht

6 Stimmen

Seine nicht Kopfschmerzen in C + + - es gibt verschiedene Möglichkeiten, um es zu erreichen. Programmierer sind weniger bewusst, C + + als c # - seine über Marketing und Investitionen ... siehe dies für verschiedene C + + Optionen, um das gleiche zu erreichen: cplusplus.com/faq/sequenzen/strings/split

11 Stimmen

@hB0 gehen durch viele Fragen Antworten und immer noch nicht entscheiden, bedeutet, ist ein Kopfschmerz. die eine braucht, dass die Bibliothek, die andere ist nur für Leerzeichen, die andere nicht behandeln Leerzeichen.

0voto

Angel Sinigersky Punkte 505

Wenn die maximale Länge der zu tokenisierenden Eingabezeichenfolge bekannt ist, kann man dies ausnutzen und eine sehr schnelle Version implementieren. Ich skizziere im Folgenden die Grundidee, die sowohl von strtok() als auch von der in Jon Bentleys "Programming Perls" (2. Auflage, Kapitel 15) beschriebenen "Suffix-Array"-Datenstruktur inspiriert wurde. Die C++-Klasse bietet in diesem Fall nur eine gewisse Organisation und Benutzerfreundlichkeit. Die gezeigte Implementierung kann leicht erweitert werden, um führende und nachfolgende Leerzeichen in den Token zu entfernen.

Grundsätzlich kann man die Trennzeichen durch string-terminierende ' \0 Zeichen und setzen Zeiger auf die Token in der geänderten Zeichenfolge. Im Extremfall, wenn die Zeichenkette nur aus Trennzeichen besteht, erhält man die Länge der Zeichenkette plus 1, was zu leeren Token führt. Es ist praktisch, die zu ändernde Zeichenkette zu duplizieren.

Header-Datei:

class TextLineSplitter
{
public:

    TextLineSplitter( const size_t max_line_len );

    ~TextLineSplitter();

    void            SplitLine( const char *line,
                               const char sep_char = ',',
                             );

    inline size_t   NumTokens( void ) const
    {
        return mNumTokens;
    }

    const char *    GetToken( const size_t token_idx ) const
    {
        assert( token_idx < mNumTokens );
        return mTokens[ token_idx ];
    }

private:
    const size_t    mStorageSize;

    char           *mBuff;
    char          **mTokens;
    size_t          mNumTokens;

    inline void     ResetContent( void )
    {
        memset( mBuff, 0, mStorageSize );
        // mark all items as empty:
        memset( mTokens, 0, mStorageSize * sizeof( char* ) );
        // reset counter for found items:
        mNumTokens = 0L;
    }
};

Implementierungsdatei:

TextLineSplitter::TextLineSplitter( const size_t max_line_len ):
    mStorageSize ( max_line_len + 1L )
{
    // allocate memory
    mBuff   = new char  [ mStorageSize ];
    mTokens = new char* [ mStorageSize ];

    ResetContent();
}

TextLineSplitter::~TextLineSplitter()
{
    delete [] mBuff;
    delete [] mTokens;
}

void TextLineSplitter::SplitLine( const char *line,
                                  const char sep_char   /* = ',' */,
                                )
{
    assert( sep_char != '\0' );

    ResetContent();
    strncpy( mBuff, line, mMaxLineLen );

    size_t idx       = 0L; // running index for characters

    do
    {
        assert( idx < mStorageSize );

        const char chr = line[ idx ]; // retrieve current character

        if( mTokens[ mNumTokens ] == NULL )
        {
            mTokens[ mNumTokens ] = &mBuff[ idx ];
        } // if

        if( chr == sep_char || chr == '\0' )
        { // item or line finished
            // overwrite separator with a 0-terminating character:
            mBuff[ idx ] = '\0';
            // count-up items:
            mNumTokens ++;
        } // if

    } while( line[ idx++ ] );
}

Ein Szenario für die Verwendung wäre:

// create an instance capable of splitting strings up to 1000 chars long:
TextLineSplitter spl( 1000 );
spl.SplitLine( "Item1,,Item2,Item3" );
for( size_t i = 0; i < spl.NumTokens(); i++ )
{
    printf( "%s\n", spl.GetToken( i ) );
}

Ausgabe:

Item1

Item2
Item3

-4voto

Karthik Punkte 1

Dies ist eine einfache Schleife zur Tokenisierung mit nur Standardbibliotheksdateien

#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <conio.h>
class word
    {
     public:
     char w[20];
     word()
      {
        for(int j=0;j<=20;j++)
        {w[j]='\0';
      }
   }

};

void main()
  {
    int i=1,n=0,j=0,k=0,m=1;
    char input[100];
    word ww[100];
    gets(input);

    n=strlen(input);

    for(i=0;i<=m;i++)
      {
        if(context[i]!=' ')
         {
            ww[k].w[j]=context[i];
            j++;

         }
         else
        {
         k++;
         j=0;
         m++;
        }

   }
 }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X