我写了这段代码。 seperateLine函数获取一个char指针,它指向一个字符串,如“S - > BaB”,并将其分配到“ - >”之前部分和“ - >”之后部分。但打印此结果会显示不同的字符串。
#include <iostream>
#include <string.h>
using namespace std;
char *seperateLine(char *line,int befOrAf){
char before[50]="";
char after[50]="";
for(int i=0;i<strlen(line);i++){
if(line[i]=='-' && line[i+1]=='>'){
strncpy(before,line,i-1);
strncpy(after, line+i+3, strlen(line)- i -3);
break;
}
}
cout<<"1 "<< before<<endl;
cout<<"1 "<<after<<endl;
if(befOrAf==0) return before;
else return after;
}
int main()
{
char grammer[10][100]={"","","S -> BaB","","","","","","",""};
char *seperated = seperateLine(grammer[2],0);
cout<<"2 "<<seperated<<endl;
seperated = seperateLine(grammer[2],1);
cout<<"2 "<<seperated<<endl;
cout<< "3 "<<seperateLine(grammer[2],0) <<endl<<"3 "<<seperateLine(grammer[2],1);
return 0;
}
输出是:
1 S
1 BaB
2 S
1 S
1 BaB
2 Ba@آH
1 S
1 BaB
1 S
1 BaB
3 S
3 j
如您所见,“S - > BaB”的第二部分在不同部分具有值“BaB”,“ba @ H”,“j”。为什么会这样?
答案 0 :(得分:1)
问题的主要部分是before
,after
是seperateLine
范围内的自动变量。一旦自动变量超出范围,它就会被销毁。死了,但并不总是消失。也许用于存储它的内存将被重新分配给其他东西,也许它不会。也许看起来它有效,也许它没有。在这种情况下你很幸运:它肯定不起作用,甚至看起来都不行。
在变量被销毁后使用它是教科书Undefined Behaviour并遵循阿甘定律:你永远不会知道你会得到什么。
传递数组是一件混乱的事情。您可以动态分配它们并将它们作为原始或智能指针返回,但在C ++中,表示字符串的char
数组的正确答案几乎总是“使用std::string
”。通常会为强调嵌入一些选择咒骂。
因此,如果std::string
可用于此作业,请使用&lt; expletive deleted&gt; std::string
。
其余问题与数组边界的松散数学有关。你需要在数组索引上用+1或-1来表示很多关心,以确保你不会偏离界限。如上所述,对数学不良可能性的最直接解决方案是使用&lt; expletive deleted&gt; std::string
。
#include <iostream>
#include <string> // changed headers string.h for c-style strings to string
// for std::string
std::string seperateLine(const std::string &line, // a reference to an immutable std::string
int befOrAf){
const static std::string delimiter = " -> "; // helps reduce magic numbers and makes it
// easier to change the token delimiter
std::string before; // now a std::string
std::string after; // also a std::string
auto loc = line.find(delimiter); // uses std::string's find method to find the arrow
if (loc != std::string::npos) // find returns npos if the arrow was not found
{
before = line.substr(0, loc); // using line's substr method to split the string
after = line.substr(loc + delimiter.size()); // look ma! No magic number!
}
std::cout<<"1 "<< before<<std::endl;
std::cout<<"1 "<<after<<std::endl;
if(befOrAf==0) return before;
else return after;
}
int main()
{
// strings, strings and more strings.
std::string grammer[10]={"","","S -> BaB","","","","","","",""};
std::string seperated = seperateLine(grammer[2],0);
std::cout <<"2 "<<seperated<<std::endl;
seperated = seperateLine(grammer[2],1);
std::cout <<"2 "<<seperated<<std::endl;
std::cout << "3 "<<seperateLine(grammer[2],0) <<std::endl
<<"3 "<<seperateLine(grammer[2],1);
return 0;
}