Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 字符串末尾的垃圾字符?_C++_String_Char_Text Extraction - Fatal编程技术网

C++ 字符串末尾的垃圾字符?

C++ 字符串末尾的垃圾字符?,c++,string,char,text-extraction,C++,String,Char,Text Extraction,大家好,我正在读一个字符串,把每个单词分解,然后把它分为姓名、电子邮件和电话号码。用字符串joe bloggsjoeblog@live.com12345。但是一旦我把所有的东西都分解了,包含姓名、电子邮件和电话号码的独立变量的末尾都有垃圾字符。我不明白为什么 测试文件 //test file #include <iostream> #include <string> #include "iofunc.h" using namespace std; int main(){

大家好,我正在读一个字符串,把每个单词分解,然后把它分为姓名、电子邮件和电话号码。用字符串
joe bloggsjoeblog@live.com12345
。但是一旦我把所有的东西都分解了,包含姓名、电子邮件和电话号码的独立变量的末尾都有垃圾字符。我不明白为什么

测试文件

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

向每个新字符串添加“\0”字符串结尾符号

字符串结尾的垃圾字符可能表示终止该字符串(以
0x00
字节结尾)不是空的。这会导致字符串继续读取,直到下一个空字符出现为止,该空字符实际上已超过字符串内存的结束位置。在某些情况下,这甚至可能导致分段错误


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

当您执行以下操作时:

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

您正在将字符串中的字符复制到name_tmp,但不是字符串结尾处的0。

其他人给您指明了正确的方向,您没有正确地终止c字符串。声明一个长度为80的字符数组只指向一个内存块,它不会以任何方式初始化数组,这意味着除非你/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;
    }

}
void iofunc::getName(字符串arg){
线性过程(arg);
//确保根据您使用的函数调用此函数
int name_count=0;
int wspace_count=0;
int arg_len=arg.length();
//int char_len=0;
字符串名称\u temp;
//如果入站arg字符串
char*cstr;
cstr=新字符[arg.size()+1];
strcpy(cstr,arg.c_str());
name_count=numberofNames();
//之前调用过line进程,所以这将起作用,
//确保在使用此函数之前调用line process
//对于特殊情况,名称前没有空格
如果(特殊条件==真){
glob_name=arg;
}
如果(特殊条件==假){
//假设至少有一个名字,我们必须把它改成原来的名字
//代码可能永远不会设置glob_名称,让我们使用C字符串函数strtok
//在每个“”处标记我们新创建的c字符串。
//抓住第一个名字。
name_temp=字符串(strtok(cstr,“”);
对于(int i=1;i
您实际在哪里阅读这些行。用什么方法。我建议您使用“fstream”。如果我像这样添加空终止字符“\0”
name\u temp[maxlen+1]='\0'
(其中max length是我复制的内容的长度),然后执行
glob\u name=string(name\u temp)操作,是否可行是,尽管添加
name_temp[i]='\0'可能会更容易char\u len=strlen(name\u temp)``名称\u temp[char\u len+1]='\0';glob_name=字符串(name_temp)我尝试过这个,但它仍然给我相同的结果result@sil3ntstrlen查找“\0”字符以查找字符串的结尾。如果\0不在那里,它将不起作用。@sil3不要使用循环索引而改为name_temp[i+1]='\0'你好,我照你说的做了,它对字符串中的两个名称起作用,但只要有三个名称,它就会做同样的事情?。你能看看我上面编辑的代码吗?。请。@sil3nt 2和3名称的代码将更新字符串中每个空格“”的索引,从而导致包含垃圾。一旦到达名称“if(wspace\u count==2)break;”或“if(wspace\u count==3)break;”的末尾,就必须停止循环
    while(i < arg_len){ 
        name_temp[i] = arg[i]; 
        i++; 
    } 
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;
    }

}