2014-10-03 6 views

risposta

2

Nessuna fortuna utilizzando strtok().

Divertente opportunità di utilizzare uno state machine.

+0

+1; Per maggiore divertimento, è possibile aggiungere facilmente anche la regola "qualunque cosa venga prima" di Javascript per "". – usr2564301

+0

Ho bisogno di qualcosa di simile tranne che dovrebbe dividere la virgola quando non è virgolette. –

6

strtok o qualsiasi altra funzione nella libreria standard C non può farlo per voi. Per ottenerlo, devi scrivere il codice da solo o devi trovare del codice esistente in qualche libreria esterna.

0

È possibile eseguire un primo passaggio in cui strtok divide la stringa utilizzando il carattere di quota come delimitatore. Quindi eseguire una seconda passata con il carattere dello spazio come delimitatore sulle stringhe risultanti non citate.

A cura di aggiungere il codice sorgente di lavoro:

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; 
} 

Credo che questo non riuscirà nel caso di stringhe tra virgolette vuote, anche se ...

+0

'strtok' rimuove il carattere split-on, in modo da perdere le informazioni su quali stringhe dividere in spazi. – usr2564301

+0

Se il primo carattere della stringa data è un carattere delimitatore, non viene distrutto. Dividerete "ogni altra" stringa risultante su spazi con l'esistenza di una citazione iniziale sulla prima sottostringa come indicatore di se state ulteriormente suddividendo le sottostringhe pari o dispari – iwolf

4

Questa funzione prende delimitare, personaggi openblock e closeblock. I caratteri di delimitazione vengono ignorati all'interno del blocco e i caratteri di blocco di chiusura devono corrispondere ai caratteri del blocco di apertura. L'esempio si divide su spazio e i blocchi sono definiti da quote e parentesi, parentesi graffe e <>. Grazie a Jongware per i commenti!

#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; 
} 

uscita
questo
contiene
blocchi
"un [blocco citato"
e
un
[blocco tra parentesi"]
e

+0

Approccio molto interessante, ma fallisce quando le virgolette appaiono all'interno di una bloccare. Forse potresti definire coppie di caratteri "aperti, chiusi"? – usr2564301

0

La mia soluzione con strtok(). Si raggruppa solo s parole che iniziano con Space-Quotes e terminano con Quotes-Space

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); 
} 
Problemi correlati