2010-08-21 171 views
2

嗨,我正在閱讀一個字符串,並打破每個單詞,並將其分類到姓名電子郵件和電話號碼。字符串爲joe bloggs [email protected] 12345。但是一旦我把所有東西都弄壞了,那些包含名字,電子郵件和電話號碼的單獨變量在它們的最後就會有垃圾字符。我無法弄清楚爲什麼。字符串結尾的垃圾字符?

測試文件

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

,這裏是我獲取命名功能,該類太大通過滾動:)

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是,使用im叫lineProcess的功能找出參數字符串中是否有電子郵件,電話和姓名,並且numberofNames函數提供了多少個姓名,以便我可以採取相應措施。

我不得不使用char name_temp從字符串中複製名稱,以便我可以提取它並將其分配給名爲glob_namestring變量。它複製我需要的所有東西,但它會在每個提取的字符串後給我那個垃圾。

有什麼想法?

EDITED

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

你究竟在哪裏讀線?用什麼方法。我建議你使用'fstream'。 – Auxiliary 2010-08-21 08:04:27

回答

0

當你做這樣的事情:

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

您在終止字符串結尾複製字符串的字符name_tmp,而不是0。

+0

它會工作,如果我像這樣'name_temp [maxlen + 1] ='\ 0''(其中最大長度是什麼複製的長度)添加空終止字符'\ 0',然後執行'glob_name = string name_temp);' – silent 2010-08-21 08:05:38

+0

是的,雖然在稍後添加'name_temp [i] ='\ 0';'可能會更容易。 – 2010-08-21 08:29:15

+0

當我有3個名字,而不是兩個,任何想法時,我仍然得到同樣的東西? – silent 2010-08-21 09:28:19

2

添加到每個新的字符串「\ 0」串符號結束

0

在字符串的結尾垃圾字符可能表明,你是不是空終止該字符串(以0x00字節結尾)。這會導致字符串繼續讀取,直到下一個空字符,該字符實際上已經到達字符串內存結束的位置。這在某些情況下甚至可能導致分段錯誤。

您可以通過將添加到您創建的每個新字符串的末尾來解決此問題。請注意,您現在必須分配一個字節的字符串來保存新的結束字符。

+0

'char_len = strlen(name_temp);''name_temp [char_len + 1] ='\ 0'; glob_name = string(name_temp);' 我試過了,但仍然給出了相同的結果 – silent 2010-08-21 08:18:43

+0

@ sil3nt strlen尋找'\ 0'字符來查找字符串的結尾。它不會工作,如果\ 0不存在。 – josefx 2010-08-21 08:26:05

+0

@ sil3nt使用你的循環索引,而不是name_temp [i + 1] ='\ 0' – josefx 2010-08-21 08:29:33

0

其他人指出你在正確的方向,你沒有適當地終止你的C字符串。聲明一個長度爲80的char數組只是指向一塊內存,它並不以任何方式初始化數組,這意味着除非你終止了你複製的字符串,否則你會得到所有的廢話最終可達80個字符。

我大概15年沒有編寫C++,所以下面的代碼甚至可能不工作,但希望它會給你一些更優雅和可維護的解決方案的想法。

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

}