我自己编写了这个非常简单的c ++函数 它应该从我的字符串中删除' - '字符 这是代码
char* FastaManager::stripAlignment(char *seq, int seqLength){
char newSeq[seqLength];
int j=0;
for (int i=0; i<seqLength; i++) {
if (seq[i] != '-') {
newSeq[j++]=seq[i];
}
}
char *retSeq = (char*)malloc((--j)*sizeof(char));
for (int i=0; i<j; i++) {
retSeq[i]=newSeq[i];
}
retSeq[j+1]='\0'; //WTF it keeps reading from memory without this
return retSeq;
}
我认为这个评论不言而喻 我不知道为什么,但是当我启动程序并打印出结果时,我会得到像
这样的东西 'stripped_sequence''original_sequence'
但是,如果我尝试调试代码以查看是否有任何错误,则流程恰到好处,并最终返回正确的剥离序列。
我试图打印出两个变量的内存,这里是内存读数
seq的内存:http://i.stack.imgur.com/dHI8k.png
retSeq的内存:http://i.stack.imgur.com/o9uvI.png
(由于垃圾邮件过滤器无法包含链接/图片,抱歉)
这是我用来打印字符串的代码
for (int i=0; i<atoi(argv[2]); i++) {
char *seq;
if (usingStructure) {
seq = fm.generateSequenceWithStructure(structure);
}else{
seq = fm.generateSequenceFromProfile();
}
cout<<">Sequence "<<i+1<<": "<<seq<<endl;
}
现在,我真的不知道发生了什么。
答案 0 :(得分:2)
如果您可以使用std :: string,只需执行以下操作:
std::string FastaManager::stripAlignment(const std::string& str)
{
std::string result(str);
result.erase(std::remove(result.begin(), result.end(), '-'), result.end());
return result;
}
这称为“erase-remove idiom”。
答案 1 :(得分:1)
这是因为您将C字符串的终止零点放在分配的空间之外。您应该在字符串副本的末尾分配一个额外的字符,并在那里添加'\0'
。或者更好的是,您应该使用std::string
。
char *retSeq = (char*)malloc((j+1)*sizeof(char));
for (int i=0; i<j; i++) {
retSeq[i]=newSeq[i];
}
retSeq[j]='\0';
它在没有这个
的情况下继续从内存中读取
这是设计使然:C字符串是零终止的。 '\0'
向C中的字符串例程发出信号,表示已到达字符串的结尾。使用C字符串时,C ++中也存在相同的约定。
答案 2 :(得分:1)
就个人而言,我认为你最好使用std::string
,除非你有其他非常好的理由:
std::string FastaManager::stripAlignment(std::string value)
{
value.erase(std::remove(value.begin(), value.end(), value.begin(), '-'), value.end());
return value;
}
当您使用C字符串时,您需要意识到它们是以空值终止的:C字符串最多可达到找到的第一个空字符。使用您发布的代码,您在分配'j'元素时引入了超出范围的赋值,并且您分配给retSeq[j + 1]
,这是字符串末尾的两个字符(无论如何你肯定是retSeq[j] = 0;
)。< / p>