2010-02-07 5 views
2

Je reçois le texte de la zone d'édition et j'aimerais que chaque nom soit séparé par une touche d'entrée comme la chaîne de caractères ci-dessous avec des caractères NULL. Comment voulez-vous faire la même chose pour la touche d'entrée (c'est-à-dire séparée par/r/n)? Division de la chaîne à la touche Entrée

char *names = "Name1\0Name2\0Name3\0Name4\0Name5"; 

    while(*names) 
    { 
     names += strlen(names)+1; 
    } 
pouvez-vous faire cela sans utiliser la classe std :: string?

+0

vous avez besoin d'un extra \ 0 à la fin de votre chaîne ou votre temps s'écoulera la fin de votre chaîne. '" .... \ 0Nom5 \ 0 "' –

+0

@John Knoeller: J'étais sur le point de faire ce commentaire, quand j'ai réalisé que l'OP parle de nouvelles lignes et non de caractères nuls. Le '\ 0 'sert d'exemple de séparateur qu'il essaie d'éliminer. – dirkgently

Répondre

2

Utilisation strstr:

while (*names) 
{ 
    char *next = strstr(names, "\r\n"); 
    if (next != NULL) 
    { 
     // If you want to use the key, the length is 
     size_t len = next - names; 

     // do something with a string here. The string is not 0 terminated 
     // so you need to use only 'len' bytes. How you do this depends on 
     // your need. 

     // Have names point to the first character after the \r\n 
     names = next + 2; 
    } 
    else 
    { 
     // do something with name here. This version is 0 terminated 
     // so it's easy to use 

     // Have names point to the terminating \0 
     names += strlen(names); 
    } 
} 

Une chose à noter est que ce code fixe également une erreur dans votre code. Votre chaîne est terminée par un simple \ 0, donc la dernière itération aura des noms pointant vers le premier octet après votre chaîne. Pour fixer votre code existant, vous devez changer la valeur des noms:

// The algorithm needs two \0's at the end (one so the final 
// strlen will work and the second so that the while loop will 
// terminate). Add one explicitly and allow the compiler to 
// add a second one. 
char *names = "Name1\0Name2\0Name3\0Name4\0Name5\0"; 
+0

mais où attraperiez-vous chaque nom de chaîne séparé? – cpx

+0

@ Dave17 - que voulez-vous dire "attraper"? Vous pouvez utiliser la chaîne au tout début du bloc if ou else. Dans le premier bloc, la chaîne n'est pas terminée à 0 mais vous connaissez le len. –

+0

Je veux dire comme ajouter chaque 'Nom' (Nom1, Nom2 ..) à array ou std :: list. comme dans le cas de '/ 0' je peux utiliser * des noms qui pointent vers le suivant. – cpx

0

Si vous voulez commencer et terminer avec une chaîne C, ce n'est pas vraiment C++.

Il s'agit d'un travail pour strsep.

#include <stdlib.h> 
void split_string(char *multiline) { 
    do strsep(&multiline, "\r\n"); 
    while (multiline); 
} 

Chaque appel à strsep Met à zéro, soit un \r ou un \n. Puisque seule la chaîne \r\n apparaît, tous les autres appels renverront un argument. Si vous le souhaitez, vous pouvez créer un tableau de char* s en enregistrant multiline au fur et à mesure de son avancement ou la valeur de retour de strsep.

void split_string(char *multiline) { 
    vector< char* > args; 
    do { 
     char *arg = strsep(&multiline, "\r\n"); 
     if (* arg != 0) { 
      args.push_back(arg); 
     } 
    } while (multiline); 
} 

Ce deuxième exemple est au moins non spécifique à Windows.

+0

@Samuel: Oui, j'ai expliqué ces deux choses. L'explication du premier extrait indique que tous les autres 'strsep' retournent une sous-chaîne. Le deuxième extrait dépouille les sous-chaînes vides générées par \ r \ n. – Potatoswatter

0

est ici une solution pure pointeur

char * names = "name1\r\nName2\r\nName3"; 
    char * plast = names; 

    while (*names) 
     { 
     if (names[0] == '\r' && names[1] == '\n') 
     { 
     if (plast < names) 
      { 
      size_t cch = names - plast; 
      // plast points to a name of length cch, not null terminated. 
      // to extract the name use 
      // strncpy(pout, plast, cch); 
      // pout[cch] = '\0'; 
      } 
     plast = names+2; 
     } 
     ++names; 
     } 

    // plast now points to the start of the last name, it is null terminated. 
    // extract it with 
    // strcpy(pout, plast); 
0

Depuis ce qui a l'étiquette C++, le plus simple serait probablement à l'aide de la bibliothèque standard C++, en particulier les chaînes et les flux de chaîne. Pourquoi voulez-vous éviter std::string lorsque vous faites du C++?

std::istringstream iss(names); 
std::string line; 
while(std::getline(iss,line)) 
    process(line); // do process(line.c_str()) instead if you need to 
Questions connexes