2010-08-21 130 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; 
    } 

}