4

您好,我正在阅读一个字符串并分解每个单词并将其分类为姓名电子邮件和电话号码。用字符串joe bloggs joeblog@live.com 12345。但是,一旦我将所有内容分解,保存名称、电子邮件和电话号码的各个分隔变量的末尾都会有垃圾字符。我不知道为什么。

测试文件

//test file
#include <iostream>
#include <string>
#include "iofunc.h"
using namespace std;
int main(){
    string str1 = "joe bloggs joeblog@live.com 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);
        }
    }

}

所有这一切的基本要点是,我使用名为 lineProcess 的函数来确定参数字符串中是否有电子邮件、电话和姓名,并且 numberofNames 函数给出了有多少个姓名,以便我可以采取相应的行动。

我不得不使用char name_temp只复制字符串中的名称,以便我可以提取它并将其分配给string名为的变量glob_name。它复制了我需要的所有内容,但在每个提取的字符串之后都会给我垃圾。

任何想法?。

已编辑

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

}
4

4 回答 4

2

当你做这样的事情时:

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

您正在将字符串的字符复制到 name_tmp,但不是末尾的 0,它终止了字符串。

于 2010-08-21T08:00:52.543 回答
2

添加到每个新字符串 '\0' 字符串结尾符号

于 2010-08-21T08:00:25.820 回答
0

字符串末尾的垃圾字符可能表明您没有以空值终止字符串(以0x00字节结尾)。这会导致字符串继续读取,直到下一个空字符,这实际上是在字符串的内存结束位置之后。在某些情况下,这甚至可能导致分段错误。

您可以通过添加'\0'到您创建的每个新字符串的末尾来解决此问题。请注意,您现在必须分配一个大一字节的字符串,以保存新的结束字符。

于 2010-08-21T08:00:38.363 回答
0

其他人已经为您指明了正确的方向,您没有适当地终止您的 c 字符串。声明一个长度为 80 的 char 数组只是指向一个内存块,它不会以任何方式初始化数组,这意味着除非你 /0 终止你复制到其中的字符串,否则你会得到所有的废话最后最多 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;
    }

}
于 2010-08-21T08:22:38.473 回答