スペースを文字に置き換えて文字列を保存する必要があります。取得するときは、文字を再びスペースに置き換える必要があります。この戦略は、保存中に (スペースを _a に) および (_a を _aa に) 置き換え、取得中に (_a をスペースに) および (_aa を _a に) 置き換えることを考えました。つまり、ユーザーが文字列に _a を入力しても処理されます。しかし、これは良い戦略だとは思いません。もっといいの持ってる人いたら教えてください
7 に答える
何かがすでに文字列に含まれている場合、スペースを何かに置き換えることは問題です。単純に文字列をエンコードしないのはなぜですか。それには多くの方法があります。その 1 つは、すべての文字を 16 進数に変換することです。
例えば
Hello world!
としてエンコードされます
48656c6c6f20776f726c6421
スペースは 0x20 です。次に、文字列を (16 進数から ASCII に) デコードするだけです。
この方法では、エンコードされた文字列にスペースがありません。
--編集- 最適化 --
%
文字列内のすべてのスペースを、文字の 16 進コードである%xx
場所に置き換えます。xx
例えば
Wine having 12% alcohol
になる
Wine%20having%2012%25%20alcohol
- %20 はスペースです
- %25 は % 文字です
このように、どちら%
も(スペース)はもはや問題ではありません - デコードは簡単です。
エンコードアルゴリズム
- replace all `%` with `%25`
- replace all ` ` with `%20`
デコードアルゴリズム
- replace all `%xx` with the character having `xx` as hex code
%1
( for%
と%2
forの2 文字だけをエンコードする必要があるため、さらに最適化することもできますが、より移植性が高く、後でより多くの文字をコーディングする必要がある場合に利用できるため、ソリューションをお勧めします)
%xx
あなたのソリューションがうまくいくかどうかわかりません。" a"
読むとき、元の文字列と元の文字列をどのように区別しますか。"_a"
正しく理解すれば、両方とも になり
"_aa"
ます。
一般に、特定の文字セットがそのままでは表示されず、エンコードする必要がある場合、解決策は、許可されている文字の 1 つを「エスケープ」文字として選択し、許可されている文字のセットから削除して、すべてをエンコードすることです。禁止文字 (エスケープ文字を含む) を、エスケープ文字で始まる 2 つ (またはそれ以上) の文字列として表します。たとえば、C++ では、文字列または文字リテラルでは改行を使用できません。エスケープ文字は
\
; そのため、エスケープ シーケンスとしてもエンコードする必要があります。したがって"\n"
、新しい行 (の選択n
は任意です)
"\\"
と\
. (の選択\
2番目の文字も任意ですが、それ自体を表すためにエスケープ文字をエスケープして使用するのがかなり一般的です。)あなたの場合、_
エスケープ文字として使用し"_a"
、スペースを表す場合、論理的な選択は"__"
a を表します(_
ただし、もう少し視覚的に暗示的なものをお勧めします。おそらく^
エスケープとして、"^_"
for a と"^^"
aを使用します^
)。読み取り時にエスケープ文字が表示されるときはいつでも、次の文字をマップする必要があります (事前定義されたマッピングの 1 つでない場合は、入力テキストがエラーになります)。これは実装が簡単で、非常に信頼性があります。唯一の欠点は、極端な場合、文字列のサイズが 2 倍になる可能性があることです。
通常の文字列では、X文字を使用して、1文字/入力文字のみを使用してx-1で文字列を記述またはエンコードすることはできません。2つの文字の組み合わせを使用して、特定の文字を置き換えることができます(これは、まさにあなたの例で試みていることです)。
これを行うには、文字列をループして、スペースの外観とその長さを組み合わせてカウントし、新しい文字配列を作成して、これらのスペースを「//」に置き換えます。これは単なる例です。このアプローチの問題は、入力文字列に「//」を含めることができないことです。
もう1つのアプローチは、スペースの代わりに「^」など、めったに使用されない文字を使用することです。
これら2つのアプローチの組み合わせで人気のある最後のアプローチ。これは、UNIXおよびPHPで使用され、文字列のリテラルとして構文文字を持ちます。"" "が必要な場合は、単に\"などと記述します。
置換機能を使ってみませんか
String* stringWithoutSpace= stringWithSpace->Replace(S" ", S"replacementCharOrText");
したがって、stringWithoutSpaceにはスペースが含まれていません。それらのスペースを元に戻したい場合は、
String* stringWithSpacesBack= stringWithoutSpace ->Replace(S"replacementCharOrText", S" ");
この質問には、見た目以上のものがあると思います。たとえば、格納する文字列にはスペースが含まれていないだけでなく、単語などのように見える必要があります。要件を明確にする必要があります (また、そのようなことを行う必要がある理由を説明することで、観客の好奇心を満足させることを検討することもできます)。
編集: JamesKanze がコメントで指摘しているように、複数の連続したスペースを使用できる場合、次の方法は機能しません。しかし、歴史的な参照のために、とにかくここに残しておきます。(連続するスペースを圧縮するように変更したため、少なくとも明確な出力が生成されます。)
std::string out;
char prev = 0;
for (char ch : in) {
if (ch == ' ') {
if (prev != ' ') out.push_back('_');
} else {
if (prev == '_' && ch != '_') out.push_back('_');
out.push_back(ch);
}
prev = ch;
}
if (prev == '_') out.push_back('_');
C/C++ を使用してこれを実装しますか? 文字列をスペースで区切って複数の部分に分割する必要があると思います。
文字列が次のような場合: "a__b" (複数のスペースが連続している)、次のように分割されます。
sub[0] = "a";
sub[1] = "";
sub[2] = "b";
これが役立つことを願っています!