web-dev-qa-db-ja.com

C ++文字列とポインタ

私はC++を学習しており、現在文字列とポインタを使用しています。

私は練習帳をフォローしていますが、質問の1つとして以下を作成しました。

#include <iostream>
#include <string>

using namespace std;

int main(void){
    string * firstName=nullptr;
    string * lastName=nullptr;
    string * displayName=nullptr;

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    displayName=new string;
    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << displayName;
    cin.get();
    return 0;
}

より多くのポインターを使用するために、私はそれを文字列と混ぜてみて、この理由でソリューションをより複雑にしました。これを実行すると、「未処理の例外:場所xxxxxxxxxを読み取るアクセス違反」が発生します。

誰かがchar配列の代わりにポインタと文字列を使用してこれの解決策を提案できますか(私はすでに方法を理解しています)?

12
Dan

これは、オブジェクトを使用する前にallocateしていないためです。

string * firstName = new string();
//...
delete firstName;

この状況でのポインタの使用は無意味であることを付け加えておきます。標準C++ライブラリの文字列オブジェクトは、ヒープから文字列のデータを割り当てます。とにかく、文字列は通常、ポインタのペアにすぎません。

15
dasblinkenlight

pointersはまったく使用したくないと思います。ポインタなしでstringsを操作できます。

#include <iostream>
#include <string>

using namespace std;

int main(void){
  string firstName;
  string lastName;
  string displayName;

  cout << "Enter your first name: " << endl;
  getline(cin,firstName);

  cout << "Enter your last name: " << endl;
  getline(cin,lastName);

  displayName= lastName + ", " + firstName;

  cout << "Here's the information in a single string: " << displayName;
  cin.get();
  return 0;
}

そうでなければ、ポインタが必要な場合は、変数にメモリを割り当てる必要があります。

  cout << "Enter your first name: " << endl;
  firstName = new string();
  getline(cin,*firstName);

...そして、逆参照演算子(*):

cout << "Here's the information in a single string: " << *displayName;
3
skywall

次のようになります。

int main()
{
    std::string* s = new std::string;
    std::getline(std::cin, *s);
    std::cout << *s;
    delete s;
}

しかし、そうする理由は本当にありません。通常の文字列変数をスタックに定義するだけです。

2
cooky451

ポインタとして文字列を使用していて、それらを初期化していないため、エラーが発生しています。これを行う正しい方法は次のとおりです。

#include <iostream>
#include <string>

using namespace std;

int main(void){
    string firstName;
    string lastName;
    string displayName;

    cout << "Enter your first name: " << endl;
    cin >> firstName;

    cout << "Enter your last name: " << endl;
    cin >> lastName;

    displayName = firstname + ' ' + lastName;


    cout << "Here's the information in a single string: " << displayName << endl;
    return 0;
}

実際には文字列へのポインタを使用できますが、それらはローカルオブジェクトとして使用され、参照(または必要に応じてconst参照)として渡されることを意図しています。

2
Dacav

アクセス違反は、nullポインターを逆参照しているためです。

Nullポインターがここに設定されています

string * firstName=nullptr;

そして、ここで逆参照されます

getline(cin,*firstName)

あなたは何か(この場合は文字列)へのファーストネーム「ポイント」が必要です。これは例外のない修正バージョンです。

int main(void){
    string * firstName= new string();
    string * lastName=new string();
    string * displayName=new string();

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    //displayName=new string;
    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << displayName->c_str();
    cin.get();
    return 0;
}
1
RobM

nullptrを使用しているので、本格的なC++ 11ソリューションも同様に問題ないと思います。

#include <iostream>
#include <memory>
#include <string>

using namespace std;

int main(void){
    unique_ptr<string> firstName(new string());
    unique_ptr<string> lastName(new string());
    unique_ptr<string> displayName(new string());

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << *displayName;
}

もちろん、nullptrを使用することは望んでいたことではありません。使用したいリソースを割り当てる必要があります。

これらの単純なケースでポインターを使用することは、構文的にもバグ的にも、自分の足を撃つことになることに注意してください。

[〜#〜] edit [〜#〜]コードを修正しました(忘れた括弧と*main)の最後の行では、GCC 4.7で正常にコンパイルおよび実行されます。

0
rubenvb

Cプログラミングの10の戒め を読んでください。今日の開発者には多かれ少なかれ時代遅れですが、2番目のものなど、いくつかはまだ重要です。

カオスと狂気があなたを待っているからです。

それが実際にここで行っていることです。ポインタがどこも指していません(std::nullptrへの割り当てを参照)。

これを修正するには、正しいクラス/構造体の新しいオブジェクトをポインターに割り当てる必要があります。また、後で削除することを忘れないでください:

std::string *myString = new std::string(); // create an object and assign it's address to the pointer

// do something with it... (this part has been right)

delete myString; // free the memory used by the object
0
Mario