【问题标题】:garbage character at end of string?字符串末尾的垃圾字符?
【发布时间】:2010-08-21 07:54:59
【问题描述】:

您好,我正在阅读一个字符串并分解每个单词并将其分类为姓名电子邮件和电话号码。使用字符串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;
}

这是我的 get 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];

    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 仅复制字符串中的名称,以便我可以仅提取该名称并将其分配给名为glob_namestring 变量。它复制了我需要的所有内容,但在每个提取的字符串之后都会给我垃圾。

有什么想法吗?

已编辑

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

}

【问题讨论】:

  • 您实际上在哪里阅读这些行。用什么方法。我建议你使用“fstream”。

标签: c++ string char text-extraction


【解决方案1】:

当你做这样的事情时:

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

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

【讨论】:

  • 如果我像这样name_temp[maxlen+1] = '\0'(最大长度是我复制的长度)添加空终止字符'\0'然后做glob_name = string(name_temp);
  • 是的,尽管在此之后立即添加name_temp[i] = '\0'; 可能会更容易。
  • 当我有 3 个名字而不是两个名字时,我仍然得到同样的东西,知道吗?
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • char_len = strlen(name_temp);``name_temp[char_len+1] = '\0';glob_name = string(name_temp); 我试过了,但结果还是一样
    • @sil3nt strlen 查找 '\0' 字符以查找字符串的结尾。如果 \0 不存在,它将无法工作。
    • @sil3nt 使用您的循环索引 name_temp[i+1] = '\0'
    • 您好,我按照您所说的做了,它适用于字符串中的 2 个名称,但只要有 3 个名称,它就会做同样的事情吗?你能看看我上面编辑的代码吗?请。
    • @sil3nt 2 和 3 名称的代码将更新字符串中每个空格 ' ' 的索引,从而导致包含垃圾。一旦到达名称“if(wspace_count == 2) break;”的末尾,就必须停止循环。或“如果(wspace_count == 3)中断;”
    【解决方案4】:

    其他人已经为您指明了正确的方向,您没有适当地终止您的 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-09-21
      • 1970-01-01
      • 2016-01-23
      • 2019-01-31
      • 2021-11-13
      • 2015-05-28
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多