2014-10-03 4 views

Antwort

2

Kein Glück mit strtok().

Spaß Gelegenheit, eine state machine zu verwenden.

+0

+1; Für zusätzlichen Spaß können Sie die Javascript-ähnliche Regel "what first first" für '' 'hinzufügen. – usr2564301

+0

Ich brauche so etwas, aber es sollte Komma trennen, wenn es keine Anführungszeichen ist. –

6

strtok oder jede andere Funktion in der Standard-C-Bibliothek kann dies nicht für Sie tun. Um es zu bekommen, müssen Sie selbst Code schreiben, oder Sie müssen einen vorhandenen Code in einer externen Bibliothek finden.

0

Sie könnten einen ersten Durchlauf durchführen, in dem strtok die Zeichenfolge mit dem Anführungszeichen als Trennzeichen aufteilt. Führen Sie dann einen zweiten Durchgang mit dem Leerzeichen als Trennzeichen für die resultierenden Zeichenfolgen aus, die nicht zitiert wurden.

Edited Arbeits Quellcode hinzuzufügen: obwohl

bool quotStr = (*stringToSplit == '\"'); 
char* currQuot = strtok(stringToSplit, "\""); 
char* next = NULL; 

while(currQuot) 
{ 
    if(quotStr) 
    { 
     printf("\"%s\"\n", currQuot); 
     quotStr = false; 
    } 
    else 
    { 
     // remember where the outer loop strtok left off 
     next = strtok(next, "\0"); 

     // subdivide 
     char* currWord = strtok(currQuot, " "); 
     while(currWord) 
     { 
      printf("%s\n", currWord); 
      currWord = strtok(NULL, " "); 
     } 
     quotStr = true; 
    } 

    currQuot = strtok(next, "\""); 
    next = NULL; 
} 

Ich glaube, das noch im Fall von leeren Strings in Anführungszeichen fehl, ...

+0

'strtok' entfernt das Split-on-Zeichen, sodass Sie die Information verlieren, welche Strings auf Leerzeichen aufgeteilt werden sollen. – usr2564301

+0

Wenn das erste Zeichen der angegebenen Zeichenfolge ein Begrenzungszeichen ist, wird es nicht zerstört. Sie teilen "jede andere" resultierende Zeichenfolge in Leerzeichen mit der Existenz eines führenden Zitats auf Ihrer ersten Teilzeichenkette als Indikator dafür, ob Sie die ungeraden oder geraden Teilzeichenfolgen weiter zerlegen. – iwolf

4

Diese Funktion nimmt abgrenzt, openblock und closeblock Zeichen. Begrenzende Zeichen werden innerhalb des Blocks ignoriert, und abschließende Blockzeichen müssen mit den öffnenden Blockzeichen übereinstimmen. Das Beispiel unterteilt sich in Leerzeichen und Blöcke werden durch Anführungszeichen und Klammern, geschweifte Klammern und <> definiert. Danke an Jongware für Kommentare!

#include<stdlib.h> 
#include<stdio.h> 
#include<string.h> 

char *strmbtok (char *input, char *delimit, char *openblock, char *closeblock) { 
    static char *token = NULL; 
    char *lead = NULL; 
    char *block = NULL; 
    int iBlock = 0; 
    int iBlockIndex = 0; 

    if (input != NULL) { 
     token = input; 
     lead = input; 
    } 
    else { 
     lead = token; 
     if (*token == '\0') { 
      lead = NULL; 
     } 
    } 

    while (*token != '\0') { 
     if (iBlock) { 
      if (closeblock[iBlockIndex] == *token) { 
       iBlock = 0; 
      } 
      token++; 
      continue; 
     } 
     if ((block = strchr (openblock, *token)) != NULL) { 
      iBlock = 1; 
      iBlockIndex = block - openblock; 
      token++; 
      continue; 
     } 
     if (strchr (delimit, *token) != NULL) { 
      *token = '\0'; 
      token++; 
      break; 
     } 
     token++; 
    } 
    return lead; 
} 

int main (int argc , char *argv[]) { 
    char *tok; 
    char acOpen[] = {"\"[<{"}; 
    char acClose[] = {"\"]>}"}; 
    char acStr[] = {"this contains blocks \"a [quoted block\" and a [bracketed \"block] and <other ]\" blocks>"}; 

    tok = strmbtok (acStr, " ", acOpen, acClose); 
    printf ("%s\n", tok); 
    while ((tok = strmbtok (NULL, " ", acOpen, acClose)) != NULL) { 
     printf ("%s\n", tok); 
    } 

    return 0; 
} 

Ausgang
diese
enthält
Blöcke
"a [zitierte Block"
und
ein
[klammert „block]
und

+0

Sehr interessanter Ansatz, aber es schlägt fehl, wenn Zitate innerhalb von a erscheinen Block. Vielleicht könnten Sie stattdessen Paare von "offenen, geschlossenen" Zeichen definieren? – usr2564301

0

Meine Lösung mit strtok(). Es ist nur eine Gruppe s Wörter, die mit Space-Quotes beginnen und mit Quotes-Space enden

void split(char *argstring) 
{ 
    int _argc = 0; 
    char **_argv = malloc(sizeof(char*)); 
    char *token; 
    int myFlag = 0; 

    for(token = strtok(argstring, " "); token != NULL; token = strtok(NULL, " ")) 
    { 
     if (1 == myFlag) 
     { 
      //One of the previous token started with double quotes 
      if ('\"' == token[strlen(token)-1]) myFlag = 0; //This token ends with double quotes 
      _argv[_argc-1] = realloc(_argv[_argc-1], strlen(_argv[_argc-1]) + strlen(token) + 2); //Enlarge the previous token 
      strcat(_argv[_argc-1], " "); 
      strcat(_argv[_argc-1], token); 
     } 
     else 
     { 
      if ('\"' == token[0]) myFlag = 1;      //This token starts with double quotes 
      _argv = realloc(_argv, (_argc + 1) * sizeof(char*)); //Add one element to the array of strings 
      _argv[_argc] = m2m_os_mem_alloc(strlen(token) + 1);  //Allocate the memory for the Nth element 
      strcpy(_argv[_argc], token);       //Copy the token in the array 
      _argc++; 
     } 
    } 

    do 
    { 
     m2m_os_mem_free(_argv[_argc--]); 
    } while (_argc >= 0); 
} 
Verwandte Themen