0

C++ では、既に初期化されている別の文字列 (文字列クラス) からインデックスごとに文字をコピーして、新しい文字列 (文字列クラス) を作成しました。

しかし、を使用してこの新しい文字列を画面に出力できませんcout。を使用c_str()して印刷できますcout。でもac系の文字列が必要なのでc_str()使う時だけ必要じゃない?printf()

#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int i;
    string a,b;
    cin>>a;
    for(i=0;a[i]!='\0';i++){
        b[i]=a[i];
    }
    cout<<b;
    return 0;
}

編集:助けてくれてありがとう!しかし、私の質問はあまり明確ではなかったかもしれないので、これらが私が抱えている主な問題です。以下をお読みください。さらにお役に立てれば幸いです。(また、b=a;割り当てる最も簡単な方法は理解していますが、文字列を理解しようとしているため、質問です。)

a)cpp文字列がいつnullで終了するのか、そうでないのかわかりませんが、この場合、ループが終了し、文字列aの最後の文字の後に終了したため、初期化後の文字列はnullで終了しました。ループしてcout<<a[i];a の最後の文字を実行すると出力されます。

b) ループ内で、インクルードcout<<b[i];すると代入後、b[i] に代入されたはずの値が出力されます。したがって、b[i] は奇妙な理由で存在します。

c) for ループの外側、プログラムの最後でcout<<b[2];、文字列の 3 番目の文字を出力するとき。そして、それを行うcout<<b.c_str();と、文字列全体が出力されます。私がそうする場合にのみcout<< b;、何も印刷されません。どうしてこれなの?

4

3 に答える 3

1

b空です。への割り当てb[i]は、 の任意の値に対して未定義の動作をしますi

a[i]!='\0'条件は、コンパイラが C++11 以降をサポートしている場合にのみ有効です。C++11 より前では、str[str.size()]未定義の動作があります。


最初にサイズを変更することで、最初の問題を修正できますb。C++11 がサポートされている場合、範囲ベースのループははるかに単純になります。C++11 がない場合は、次のオプションが有効です。

b.resize(a.size());
for(i=0; i < a.size(); i++)

ただし、文字列をコピーするループを書くのは少しばかげています。単純に割り当てを使用できます。

b = a;

a)cpp文字列がいつnullで終了するのか、そうでないのかわかりませんが、この場合、ループが終了し、文字列aの最後の文字の後に終了したため、初期化後の文字列はnullで終了しました。ループしてcout<<a[i];a の最後の文字を実行すると出力されます。

(C++11 を有効にしてコンパイルしていないと仮定します) これは、オペレーティング システムでコンパイラを使用してコンパイルし、その特定の時点で CPU でプログラムを実行したときに観察したことです。いずれかの要因が変更された場合、動作が同じであるという保証はありません。

b) ループ内で、割り当て後にインクルードcout<<b[i];すると、割り当てられたばかりであると予想される値が出力されb[i]ます。いくつb[i]かの奇妙な理由で存在します

b[1]「存在する」という意味ではありません。動作は未定義です。

c) for ループの外側、プログラムの最後でcout<<b[2];、文字列の 3 番目の文字を出力するとき。そして、それを行うcout<<b.c_str();と、文字列全体が出力されます。私がそうする場合にのみcout<< b;、何も印刷されません。どうしてこれなの?

これは、動作が未定義であるためです。

于 2016-09-28T13:51:55.327 に答える