Esiste un modo per farlo con la funzione strtok
? o qualche suggerimento?In c split char * su spazi con funzione strtok, tranne se tra virgolette
Esempio:
Insert "hello world" to dbms
Risultato:
Insert
"hello world"
to
dbms
Esiste un modo per farlo con la funzione strtok
? o qualche suggerimento?In c split char * su spazi con funzione strtok, tranne se tra virgolette
Esempio:
Insert "hello world" to dbms
Risultato:
Insert
"hello world"
to
dbms
Nessuna fortuna utilizzando strtok()
.
Divertente opportunità di utilizzare uno state machine.
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.
Forse si può usare un espressione regolare (cioè Regular expressions in C: examples?)
Ecco un esempio di espressione regolare si può usare: /([\w]+)|(\"[\w\ ]+\")/gi
allenarti con regex si dovrebbe anche usare: http://regex101.com/
È 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 ...
'strtok' rimuove il carattere split-on, in modo da perdere le informazioni su quali stringhe dividere in spazi. – usr2564301
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
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
Approccio molto interessante, ma fallisce quando le virgolette appaiono all'interno di una bloccare. Forse potresti definire coppie di caratteri "aperti, chiusi"? – usr2564301
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);
}
+1; Per maggiore divertimento, è possibile aggiungere facilmente anche la regola "qualunque cosa venga prima" di Javascript per "". – usr2564301
Ho bisogno di qualcosa di simile tranne che dovrebbe dividere la virgola quando non è virgolette. –