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