2010-08-21 5 views
2

Salut, je suis en train de lire une chaîne et de casser chaque mot et de le trier en nom email et numéro de téléphone. avec la chaîne joe bloggs [email protected] 12345. Mais une fois que je casse tout, les variables séparées individuelles qui contiennent le nom, le courriel et le numéro de téléphone ont des caractères de poubelle à la fin de ceux-ci. Je n'arrive pas à comprendre pourquoi.caractère de poubelle à la fin de la chaîne?

fichier test

//test file 
#include <iostream> 
#include <string> 
#include "iofunc.h" 
using namespace std; 
int main(){ 
    string str1 = "joe bloggs [email protected] 12345"; 

    iofunc func; 
    cout<<"|-----------------------getname DEMONSTRATION------------------|\n" << endl; 
    func.getName(str1); 

    cout<<"the names are: " << func.glob_name << endl; 

    cout<<"\n|-----------------------getphone DEMONSTRATION------------------|\n" << endl; 
    func.getPhone(str1); 
    cout<<"the phone number is:" << func.glob_phone << endl; 

    cout<<"\n|-----------------------getemail DEMONSTRATION------------------|\n" << endl; 
    func.getEmail(str1); 
    cout<<"the email address is:" << func.glob_email << endl; 


    return 0; 
} 

ici est ma fonction de nom get, la classe est trop grand pour faire défiler :)

void iofunc::getName(string arg){ 
    lineProcess(arg); 
    //make sure to call this depending on what function u are using 

    int name_count = 0; 
    int wspace_count = 0; 
    int arg_len = arg.length(); 
    //int char_len = 0; 
    char name_temp[80]; 

    name_count = numberofNames(); 
    //line process was called before so this will work, 
    //make sure you call line process before using this function 

    //for special, condition when there is no space in front of names 
    if (special_condition == true){ 
     int i = 0; 
     while(i < arg_len){ 
      name_temp[i] = arg[i]; 
      i++; 
     } 
     glob_name = string(name_temp); 

    } 

    if (special_condition == false){ 
     if (name_count == 1){ 
      int i = 0; 
      while (arg[i] != ' '){ 
       name_temp[i] = arg[i]; 
       i++; 
      } 
      glob_name = string(name_temp); 
     } 

     //for 2 names 
     if (name_count == 2){ 
      for (int i = 0; i < arg_len;i++){ 
       if (arg[i] == ' '){ 
        wspace_count++; 
       } 
       if (wspace_count !=2){ 
        name_temp[i] = arg[i]; 
       } 
      } 
      glob_name = string(name_temp); 
     } 
     //for 3 names 
     if (name_count == 3){ 
      for (int i = 0; i < arg_len;i++){ 
       if (arg[i] == ' '){ 
        wspace_count++; 
       } 
       if (wspace_count !=3){ 
        name_temp[i] = arg[i]; 
       } 
      } 
      glob_name = string(name_temp); 
     } 
    } 

} 

jist base de tout ce qui est, im en utilisant la fonction appelée lineProcess à déterminer s'il y a un email, un téléphone et un nom dans la chaîne d'argument, Et les fonctions numberofNames indiquent combien de noms il y a pour que je puisse agir en conséquence.

Je devais utiliser char name_temp pour copier seulement les noms de chaîne afin que je puisse extraire juste cela et l'assigner à la variable string nommée glob_name. Il copie tout ce dont j'ai besoin mais il me donne cette poubelle après chaque chaîne extraite.

une idée ?.

ÉDITÉE

void iofunc::getName(string arg){ 
    lineProcess(arg); 
    //make sure to call this depending on what function u are using 

    int name_count = 0; 
    int wspace_count = 0; 
    int arg_len = arg.length(); 
    //int char_len = 0; 
    char name_temp[80]; 
    int index_track = 0; 

    name_count = numberofNames(); 
    //line process was called before so this will work, 
    //make sure you call line process before using this function 

    //for special, condition when there is no space in front of names 
    if (special_condition == true){ 
     int i = 0; 
     while(i < arg_len){ 
      name_temp[i] = arg[i]; 
      index_track = i; 
      i++; 
     } 
     name_temp[index_track+1] = '\0'; 
     glob_name = string(name_temp); 

    } 

    if (special_condition == false){ 
     if (name_count == 1){ 
      int i = 0; 
      while (arg[i] != ' '){ 
       name_temp[i] = arg[i]; 
       index_track = i; 
       i++; 
      } 
      name_temp[index_track+1] = '\0'; 
      glob_name = string(name_temp); 
     } 

     //for 2 names 
     if (name_count == 2){ 
      for (int i = 0; i < arg_len;i++){ 
       if (arg[i] == ' '){ 
        wspace_count++; 
       } 
       if (wspace_count !=2){ 
        name_temp[i] = arg[i]; 
        index_track = i; 
       } 
      } 
      name_temp[index_track+1] = '\0'; 
      glob_name = string(name_temp); 
     } 
     //for 3 names 
     if (name_count == 3){ 
      for (int i = 0; i < arg_len;i++){ 
       if (arg[i] == ' '){ 
        wspace_count++; 
       } 
       if (wspace_count !=3){ 
        name_temp[i] = arg[i]; 
        index_track = i; 
       } 
      } 
      name_temp[index_track+1] = '\0'; 
      glob_name = string(name_temp); 
     } 
    } 

} 
+0

Où lisez-vous réellement les lignes. Avec quelle méthode. Je vous suggère d'utiliser le 'fstream'. – Auxiliary

Répondre

0

Lorsque vous faites des choses comme ceci:

while(i < arg_len){ 
     name_temp[i] = arg[i]; 
     i++; 
    } 

Vous copiez les caractères de la chaîne à name_tmp, mais pas 0 à la fin qui met fin à la chaîne.

+0

cela fonctionnerait-il si j'ajoutais le caractère de terminaison nul '\ 0' comme ceci 'nom_temp [maxlen + 1] = '\ 0' (où longueur maximale est la longueur de ce que ive a copié) et fais ensuite 'glob_name = string (name_temp); ' – silent

+0

Oui, bien qu'il soit probablement plus facile d'ajouter' name_temp [i] = '\ 0'; 'immédiatement après. –

+0

Je reçois toujours la même chose quand j'ai 3 noms au lieu de deux, une idée? – silent

2

ajouter à chaque nouvelle chaîne « \ 0 » fin de symbole de chaîne

0

caractères ordures à la fin d'une chaîne pourrait indiquer que vous n'êtes pas nul de terminaison la chaîne (se terminant par 0x00 octet). Cela provoque la lecture de la chaîne jusqu'au prochain caractère nul, qui est en fait passé à l'endroit où se termine la mémoire de la chaîne. Cela pourrait même provoquer une erreur de segmentation dans certains cas.

Vous pouvez résoudre ce problème en ajoutant '\0' à la fin de chaque nouvelle chaîne que vous créez. Notez que vous devrez allouer une chaîne un octet plus grand maintenant, pour contenir ce nouveau caractère de fin.

+0

'char_len = strlen (nom_temp);' 'nom_temp [char_len + 1] = '\ 0'; glob_name = chaîne (nom_temp);' J'ai essayé ceci, mais il me donne toujours le même résultat – silent

+0

@ sil3nt strlen cherche le caractère '\ 0' pour trouver la fin de la chaîne. Cela ne fonctionnera pas si le \ 0 n'est pas là. – josefx

+0

@ sil3nt utilisez votre index de boucle à la place nom_temp [i + 1] = '\ 0' – josefx

0

Les autres vous ont indiqué la bonne direction, vous ne terminez pas correctement vos chaînes de caractères. Déclarer un tableau char de longueur 80 ne pointe que sur un bloc de mémoire, il n'initialise pas le tableau de quelque façon que ce soit, cela signifie qu'à moins que vous/0 terminiez la chaîne que vous copiez dedans, vous obtiendrez toutes les conneries à la fin jusqu'à 80 caractères.

Je n'ai pas écrit de C++ depuis probablement 15 ans, donc le code ci-dessous peut ne pas fonctionner, mais j'espère qu'il vous donnera quelques idées pour une solution plus élégante et maintenable.

void iofunc::getName(string arg){ 
    lineProcess(arg); 
    //make sure to call this depending on what function u are using 

    int name_count = 0; 
    int wspace_count = 0; 
    int arg_len = arg.length(); 
    //int char_len = 0; 
    string name_temp; 

    // Let's assemble a c-str version if the inbound arg string 
    char* cstr; 
    cstr = new char [arg.size()+1]; 
    strcpy (cstr, arg.c_str()); 

    name_count = numberofNames(); 
    //line process was called before so this will work, 
    //make sure you call line process before using this function 

    //for special, condition when there is no space in front of names 
    if (special_condition == true){ 
     glob_name = arg; 
    } 

    if (special_condition == false){ 
     // Assuming there's at least 1 name, which we have to otherwise the original 
     // code may never set glob_name, let's use the C String function strtok 
     // to tokenise our newly created c string at each " ". 
     // Grab the first name. 
     name_temp = string(strtok(cstr, " ")); 
     for (int i = 1; i < name_count; i++) { 
      // Grab names 2 to name_count as required and append them to name_temp 
      // We need to reinsert the space as strtok doesn't grab it. 
      name_temp += " " + string(strtok(NULL, " ")); 
     } 
     // Assign our final name to glob_name 
     glob_name = name_temp; 
    } 

} 
Questions connexes