我正在编写一个小程序,它将所有正整数的出现转换为二进制整数。那么我该如何写这个:
我有一个函数numbersToBinary,它接受一个字符串并对其进行修改,因此它将包含二进制形式的数字,而不是十进制数字。
void numbersToBinary(string &src)
{
for (string::iterator iter = src.begin(); iter != src.end(); iter++)
{
if (isdigit(*iter))
{
string::iterator numberStart = iter++; //numberStart = iter;
while ((iter != src.end()) && (isdigit(*iter)))
{
iter++;
}
string ins = decimalToBinary(string(numberStart, iter));
src.replace(numberStart, iter, ins);
}
}
}问题是,当使用以数字结尾的字符串调用替换方法时,此函数会捕获异常。
下面是一个要旨:有代码,您也可以在这里看到:github。单元测试是可用的
MWE:
using namespace std;
int main() {
string example = "String123Primer";
numbersToBinary(example);
cout << example << endl; //"String1111011Primer
return 0;
}实际工作的函数:
void numbersToBinary(string &src)
{
for (int i = 0; i < src.length(); ++i)
{
if (isdigit(src[i]))
{
int numberStart = i++; //numberStart = iter;
while (src.length() != i && (isdigit(src[i])))
{
++i;
}
string ins = decimalToBinary(src.substr(numberStart, i-numberStart));
src.replace(numberStart, i-numberStart, ins);
}
}
}编辑:我创建了这个函数的新版本:
void numbersToBinary(string &src) {
string newString;
for (string::iterator iter = src.begin(); iter != src.end(); iter++) {
if (isdigit(*iter)) {
string::iterator numberStart = iter++; //numberStart = iter;
while ((iter != src.end()) && (isdigit(*iter))) {
iter++;
}
string ins = decimalToBinary(string(numberStart, iter));
newString.append(ins);
}
else
newString.push_back(*iter);
}
src = newString;
}但是事实证明,条件(iter != src.end())从来都不是假的,即使在字符串结束时也是如此:
Breakpoint 2, numbersToBinary (src="My favourite number is13and nevermind 13") at /home/pasha/projects/miem/Replacer/func.cpp:58
58 newString.append(ins);
(gdb) print ins
$40 = "1101"
(gdb) s
51 for (string::iterator iter = src.begin(); iter != src.end(); iter++) {
(gdb) print iter
$41 = 0 '\000'
(gdb) s
__gnu_cxx::__normal_iterator<char*, std::string>::operator++ (this=0x7fffffffd7d0) at /usr/include/c++/4.9.1/bits/stl_iterator.h:757
757 { return __normal_iterator(_M_current++); }
(gdb) s
__gnu_cxx::__normal_iterator<char*, std::string>::__normal_iterator (this=0x7fffffffd780, __i=@0x7fffffffd788: 0x6a1a10 "") at /usr/include/c++/4.9.1/bits/stl_iterator.h:729
729 : _M_current(__i) { }
(gdb) s
__gnu_cxx::operator!=<char*, std::string> (__lhs=16 '\020', __rhs=0 '\000') at /usr/include/c++/4.9.1/bits/stl_iterator.h:832
832 { return __lhs.base() != __rhs.base(); }
(gdb) s
__gnu_cxx::__normal_iterator<char*, std::string>::base (this=0x7fffffffd7d0) at /usr/include/c++/4.9.1/bits/stl_iterator.h:794
794 { return _M_current; }
(gdb) s
__gnu_cxx::__normal_iterator<char*, std::string>::base (this=0x7fffffffd810) at /usr/include/c++/4.9.1/bits/stl_iterator.h:794
794 { return _M_current; }
(gdb) s
numbersToBinary (src="My favourite number is13and nevermind 13") at /home/pasha/projects/miem/Replacer/func.cpp:52
52 if (isdigit(*iter)) {
(gdb) print iter
$42 = 16 '\020'
(gdb) print src.end()
$43 = 0 '\000'编辑:难以置信,如果我加上这个
if (iter == src.end()) break;在for循环结束之前,它可以工作!这是什么?
发布于 2014-10-06 21:22:52
关于最新的(和.(更新)密码..。
编辑:难以置信,如果我加上这个 若(iter == src.end())断裂; 在for循环结束之前,它可以工作!这是什么?
这并不难以置信。这就是循环的工作原理。您需要了解for-循环的增量步骤是何时执行的,而条件步骤是何时计算的。
在输入循环主体(Re)之前,在之前执行条件eval。增量步骤是在完成循环主体之后,在返回到下一个条件评估的循环顶部之前执行的。
简而言之,如果内部数字循环将迭代器运行到src.end(),则您的for循环增量步骤将增加一个已经位于序列末尾的迭代器。记住,for循环增量是在每次迭代完成之后,但在下一个条件测试之前完成的。
因此,
void numbersToBinary(string &src)
{
string newString;
string::iterator iter = src.begin();
while (iter != src.end())
{
if (isdigit(*iter))
{
string::iterator numberStart = iter++; //numberStart = iter;
while ((iter != src.end()) && (isdigit(*iter))) {
++iter;
}
string ins = decimalToBinary(string(numberStart, iter));
newString.append(ins);
}
else
{
newString.push_back(*iter++);
}
}
src = newString;
}是你尝试的几种方法之一。如果iter已经到达src.end(),您也可以在循环的末尾设置一个硬中断(尽管在那里检查似乎有些多余,因为我们已经知道它被设置为src.end():数字循环)。
发布于 2014-10-06 21:22:41
调用replace后,原始字符串值不再存在。所以它的部分迭代器不再有效。当您再次循环时,iter是一个迭代器,它是一个不再存在的值的一部分,因此将它与完全不同的值的结尾end进行比较是毫无意义的。调用replace之后,在将iter与end进行比较之前,需要将它设置为新字符串中正确的新值。
https://stackoverflow.com/questions/26223242
复制相似问题