0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++で文字列を連結する時につまづいたこと

Last updated at Posted at 2024-10-17

環境

M1 MacBook
Sonoma 14.6.1

何につまづいたのか

文字列の連結をC++で実装する時につまづきました。クエリを受け取り、それに応じて文字列を生成してスタックするという処理です。

どこでつまづいたのか

...
string ans = "";
string S = flw[i];
for (const auto &v: S)
    ans += v + " ";
out.push_back(ans);
...

上が該当のコードです。outにスタックされた文字列は、処理の最後にまとめて出力されます。しかしながら、このプログラムを実行しても、何も出力されませんでした。

原因

原因は、文字型と文字列型の混同でした。C++は、文字列同士を「+」演算子で連結できます。

string a = "abc" + "def";
cout << a << endl;
abcdef

しかしながら、私は次の様なコードを書いてしまいました。

...
ans += v + " ";
...

2024/10/18 修正

この時、vがstring型であれば、問題なく連結されます。しかし、vはchar型でしたので、意図しない動作が発生しました。

しかし、上の実装を見るとわかりますように、for文で文字列型の要素である文字型を取り出していますので、この式は「文字型」と「文字列型」の連結を行おうとしてしまいます。本来であれば、コンパイラがエラーを示してくれるはずですが、for文内部でauto型を使ってしまったせいで、コンパイラも気が付かなかった様です。
(コンパイラは正しく型推論を行なっています)

改善

2024/10/18 修正

to_string関数を用いてstring関数を用いて文字型を文字列型に変換しました。これで、文字が問題なく連結されるようになりました。

ans += string(1, v) + " ";

未だわからないところ・予想など

コメントより、上記のコードは問題なく動作するとの指摘を受けましたので、一度実験を行いました。

string ans = "";
const char &v = 'a';
const char* space = " ";
space += v;
ans += space;
cout << ans << endl;
$ ./a.out
$ ?

文字がうまく連結されませんでした。もしかしたら、コメント投稿者の方と環境が異なったり、私のプログラムがよくないのかもしれません。ただ、まだ気になりましたので、もう少し実験を行いました。

出力結果に「?」と表示されたところが気になりました。文字型に間違えて数字を足しますと、時々文字がずれて、このような結果になります。もしかしたら、文字同士がASCIIの数字で足し算されているのではないかと予想しました。

実験1

print(" " + 'a');
print(" " + 97);
$ ./a.out 
[空白]
[空白]

実験2

print("" + 'a');
print("" + 97);
$ ./a.out 
???????<
???????<

あくまでも知識不足の私の予想なのですが、もしかしたら文字が整数値に変換されてしまい、上のような挙動が起きたのではないかと思います。整数を文字列に足すことで、ポインタ操作が行われてしまったのかもしれません。いずれにせよ、未だよくわからない領域です。引き続き、勉強してまいります。

参考

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?