文字列 txt, in-placeから特定の文字を削除する方法を実装していました。以下は私のコードです。結果は「bdeg」として期待されます。ただし、結果は「bdegfg」で、null ターミネータが設定されていないようです。奇妙なことは、nullターミネータを設定した後、gdbを使用してデバッグするときです
(gdb) p txt
$5 = (std::string &) @0xbffff248: {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x804b014 "bdeg"}}
それは私には正しく見えます。では、ここで何が問題なのですか?
#include <iostream>
#include <string>
using namespace std;
void censorString(string &txt, string rem)
{
// create look-up table
bool lut[256]={false};
for (int i=0; i<rem.size(); i++)
{
lut[rem[i]] = true;
}
int i=0;
int j=0;
// iterate txt to remove chars
for (i=0, j=0; i<txt.size(); i++)
{
if (!lut[txt[i]]){
txt[j]=txt[i];
j++;
}
}
// set null-terminator
txt[j]='\0';
}
int main(){
string txt="abcdefg";
censorString(txt, "acf");
// expect: "bdeg"
std::cout << txt <<endl;
}
フォローアップの質問:
文字列が c 文字列のように切り詰められていない場合。それで何が起こるtxt[j]='\0'
のか、なぜそれが「bdeg'\0'g」またはいくつかの破損した文字列ではなく「bdegfg」なのか。
別のフォローアップ:私が使用する場合 txt.erase(txt.begin()+j, txt.end()
); それは正常に動作します。だから私は文字列関連のAPIを使ったほうがいいです。ポイントは、これらの API の基礎となるコードの時間の複雑さがわからないということです。