2016-06-10 4 views
0

Als Beispiel Eingang konvertieren:Ich habe einen String str, die zwei Array hat (sein können), die Ich mag würde auf ganzzahlige Arrays in C

c[] = "[1,2,3][5,7,8]" 

Output:

a = [1,2,3] //of type int a[] 
b = [5,7,8] //of type int b[] 

Ich habe versucht, strtok zu verwenden, um "]" zu entfernen. Aber wenn ich strtok das nächste Mal benutze, kann ich es nicht benutzen. Wenn ich versuche, die Ausgabe zu drucken, erhalte ich

[1,2,3 
[1 
2 
3 

statt

[1,2,3 
[1 
2 
3 
[5,7,8 
[5 
7 
8 

-Code, die ich bisher ist

char c[] = "[1,2,3][5,7,8]"; 

char *token = strtok(c, "]"); 
for (token; token != NULL ; token = strtok(NULL, "]")){ 
    puts(token); 
    char *comma = strtok(c, ","); 
    for (comma; comma != NULL; comma = strtok(NULL, ",")){ 
     puts(comma); 
    } 
} 
+0

Können Sie bitte die erforderliche Ausgabe klären? Das syntaktisch inkorrekte Beispiel * input * wird im Codebeispiel geklärt, aber die erste Beispielausgabe wird als '// vom Typ int a []' kommentiert. Meinst du, dass die Ausgabe "int a [] = {1, 2, 3}" ist? Und das nächste Beispiel * "statt" * stimmt nicht mit dem ersten Beispiel überein. –

+0

'strtok' wird nicht funktionieren, weil Sie nach einem Komma * oder *'] 'suchen müssen. 'strtok' kann das tun, aber es wird dir nicht sagen, welches es gefunden hat. Sie müssen also die Zeichenfolge selbst analysieren, indem Sie eine 'for'-Schleife verwenden, die jeweils ein Zeichen untersucht. – user3386109

+0

@WeatherVane Ja, ich meinte ein [] = {1, 2, 3}. Entschuldigung für die Verwirrung. – user3213116

Antwort

0

Ihr Problem haben, dass strtok a hat Erinnerung. Das erste Mal, dass Sie eine Zeichenfolge übergeben, wird sie gespeichert und dann immer wieder verwendet, solange Sie NULL als ersten Parameter übergeben.

Innerhalb Ihrer Schleife rufen Sie jedoch erneut strtok mit einen Parameter. Diese neue Zeichenfolge (die nur das erste Token ist) wird also in den Speicher von strtok gestellt, und nachdem sie vollständig in der inneren Schleife verarbeitet wurde, ist nichts mehr in der äußeren Schleife zu tokenisieren.

Werfen Sie einen Blick auf diese thread, es erklärt ausführlicher, wie strtok funktioniert.

Allerdings haben Sie Glück: strtok manipuliert die Zeichenfolge, die Sie zuerst an Ort und Stelle übergeben haben (deshalb müssen Sie die Zeichenkette als char* übergeben, aber die Trennzeichen können eine const char* sein). So können Sie dies tun:

char c[] = "[1,2,3][5,7,8]"; 

char* next = c; 
char* token; 
while((token = strtok(next, "]"))) 
{ 
    puts(token); 
    next += strlen(token) + 1; // move next behind the token 
    token = strtok(token, ","); 
    do 
    { 
     puts(token); 
    } 
    while((token = strtok(NULL, ","))); 
} 

Wenn Sie über die zusätzlichen Klammern fragen, sind diese eine Warnung in den Compiler zu verhindern („mögliche Zuordnung statt Vergleich“).

0

Diese Lösung hat zwei verschachtelte Schleifen von strtok_s, weil strtok nicht einspringt. Dies ist MSVC, einige Systeme implementieren die ähnliche strtok_r.

Ich habe Ausgabe in Übereinstimmung mit der Oberseite Ihrer Frage geschaffen, dieses kann geändert werden, um anderen Ausgang zu entsprechen, es war nicht sehr klar. In diesem Fall war es nicht wirklich notwendig, zwei verschachtelte Schleifen zu haben, aber Ihre nachfolgenden Beispiele verwirren das Problem, indem Sie die komma-Eingabe auflösen.

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

int main(void) { 
    char c[] = "[1,2,3][5,7,8]"; 
    char *tok1 = NULL; 
    char *tok2 = NULL; 
    char *end1 = NULL; 
    char *end2 = NULL; 
    int comma = 0; 
    char identifier = 'a'; 

    tok1 = strtok_s(c, "[]", &end1); 
    while(tok1 != NULL) {      // outer loop splitting [bracket] parts 
     printf("%c = [", identifier); 
     comma = 0;        // control comma output 
     tok2 = strtok_s(tok1, ",", &end2); 
     while(tok2 != NULL) {     // inner loop splitting ,comma, parts 
      if(comma) {       // check if comma required 
       printf(","); 
      } 
      printf("%s", tok2); 
      comma = 1;       // a comma will be needed 
      tok2 = strtok_s(NULL, ",", &end2); 
     } 
     printf("] //of type int %c[]\n", identifier); 
     identifier++; 
     tok1 = strtok_s(NULL, "[]", &end1); 
    } 
    return 0; 
} 

Die einfachere Programm, wo Sie brauchen nicht in den [Klammern] zu prüfen, ist die Ausgabe

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

int main(void) { 
    char c[] = "[1,2,3][5,7,8]"; 
    char *tok = NULL; 
    char identifier = 'a'; 

    tok = strtok(c, "[]"); 
    while(tok != NULL) { 
     printf("%c = [%s] //of type int %c[]\n", identifier, tok, identifier); 
     identifier++; 
     tok = strtok(NULL, "[]"); 
    } 
    return 0; 
} 

In beiden Fällen wird:

a = [1,2,3] //of type int a[] 
b = [5,7,8] //of type int b[] 

EDIT verändert die zweites Beispiel, um die Ausgabe gemäß dem obigen Kommentar von OP zu geben.

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

int main(void) { 
    char c[] = "[1,2,3][5,7,8]"; 
    char *tok = NULL; 
    char identifier = 'a'; 

    tok = strtok(c, "[]"); 
    while(tok != NULL) { 
     printf("int %c[] = { %s };\n", identifier, tok, identifier); 
     identifier++; 
     tok = strtok(NULL, "[]"); 
    } 
    return 0; 
} 

Programmausgang:

int a[] = { 1,2,3 }; 
int b[] = { 5,7,8 }; 
+0

@ user3213116 Ich habe diese Antwort nach Ihrem letzten Kommentar über die Ausgabe bearbeitet. –

0

Wenn Sie eine Reihe von Zeichen Ziffern auf ein Array von ganzzahligen Werten konvertieren, ein Zeichen pro Wert (oder ermöglicht ein - bevor eine Zeichenzahl A , um anzuzeigen, negative Wert für Ihr Array), sollten Sie besser eine einfache Funktion schreiben, um die Zeichenfolge zu durchlaufen und Ihre Conversions manuell durchzuführen.

Ein Beispiel mit Array Indizierung der Zeichenfolge könnte folgendermaßen geschrieben werden. Sie könnten die Array-Index-Notationen leicht in Pointer-Notation ändern, was für einige intuitiver ist.

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

size_t str2arr (char *d, size_t max, char *s, size_t *ofs); 

int main (int argc, char **argv) { 

    char c[] = "[1,2,3][5,7,8]"; 
    char *p = argc > 1 ? argv[1] : c; 
    size_t i, offset = 0, na = 0, nb = 0, nchr = strlen (p); 
    char a[nchr], b[nchr]; 

    memset (a, 0, nchr * sizeof *a); /* zero each VLA */ 
    memset (b, 0, nchr * sizeof *b); 

    na = str2arr (a, nchr, p, &offset);   /* convert first segment */ 
    nb = str2arr (b, nchr, p + offset, &offset); /* convert second segment */ 

    for (i = 0; i < na; i++)      /* output results */ 
     printf (" a[%2zu] : % d\n", i, a[i]); 
    putchar ('\n'); 

    for (i = 0; i < nb; i++) 
     printf (" b[%2zu] : % d\n", i, b[i]); 
    putchar ('\n'); 

    return 0; 
} 

/** convert a string of characters to an array of values 
* including accounting for negative values. the destination 
* index `di` returns the number of characters conversions, the 
* offset of the next segment within 's' is updated in pointer 'ofs' 
*/ 
size_t str2arr (char *d, size_t max, char *s, size_t *ofs) 
{ 
    if (!d || !s || !*s) return 0; /* validate input */ 
    size_t di = 0, neg = 0; 
    register size_t si = 0; 

    for (; di < max && s[si]; si++, di++) {  /* for each character */ 
     if (s[si] == ']') break; 
     while (s[si] && (s[si] < '0' || ('9' < s[si]))) { /* if not digit */ 
      if (s[si] == '-') neg = 1;   /* if '-' sign, set flag */ 
      else neg = 0;    /* clear if not last before digit */ 
      si++; 
     } 
     if (!s[si]) break;     /* validate not end of string */ 
     d[di] = neg ? -(s[si] - '0') : s[si] - '0'; /* convert to digit */ 
     neg = 0;          /* reset flag */ 
    } 

    *ofs = si + 1; /* update offset before return */ 

    return di;  /* return number of conversions */ 
} 

Beispiel Verwendung/Output

$ ./bin/str2arr 
a[ 0] : 1 
a[ 1] : 2 
a[ 2] : 3 

b[ 0] : 5 
b[ 1] : 7 
b[ 2] : 8 

$ ./bin/str2arr "[1,2,3,4][5,6,-5,7,-1,8,9,2]" 
a[ 0] : 1 
a[ 1] : 2 
a[ 2] : 3 
a[ 3] : 4 

b[ 0] : 5 
b[ 1] : 6 
b[ 2] : -5 
b[ 3] : 7 
b[ 4] : -1 
b[ 5] : 8 
b[ 6] : 9 
b[ 7] : 2 

es Schauen Sie über, zu vergleichen, diesen Ansatz zu den anderen Antworten. In C haben Sie genau so viel Kontrolle darüber, wie Sie Daten analysieren, wenn Sie sie trainieren möchten. Wenn Sie keine negativen Werte behandeln müssen, dann ist die Implementierung viel einfacher. Lass es mich wissen, wenn du irgendwelche Fragen hast.

Verwandte Themen