我创建了一个函数,它将一个数字转换为它在给定基数中的等价数并将其打印成一个字符串。它看起来完美无瑕但却给出了荒谬的结果。下面的代码应该将100转换为基数9并给出“121”。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void doldur(string *s,int u,int base){
*s="";
while(u!=0){
*s=""+u%base+*s;
u/=base;
}
return;
}
int main() {
ofstream fout ("dualpal.out");
ifstream fin ("dualpal.in");
int i;
string hey;
doldur(&hey,100,9);
cout<<hey;
cin>>i;
return 0;
}
但可笑的是,它打印了dualpal.outualpal.outdualpal.out。(还为不同的基础提供了其他有趣的结果)
缺陷在哪里?
答案 0 :(得分:4)
您正在通过u%base
个位置将指针添加到空字符串,然后使用它来构造std::string
,它会查找空终止符。这会导致未定义的行为。立即使用std::string
:
*s = std::string() + ...;
接下来,没有从int
到std::string
的转换。使用std::to_string
:
*s = std::to_string(u%base) + *s;
第一个操作数现在没有意义,所以我删除了它。最后,所有这些解除引用都有点令人厌烦,不是吗?我会制作一个并将其归还:
std::string doldur(const std::string &s,int u,int base){
std:string ret;
while(u!=0){
ret = std::to_string(u%base) + ret;
u/=base;
}
return ret;
}
不要担心返回时会造成任何性能损失。或者如果您愿意,可以使用参考文献并更改原文:
void doldur(std::string &s,int u,int) {
s.clear();
while(u!=0){
s = std::to_string(u%base) + s;
u/=base;
}
}