• ベストアンサー

C++の基礎的な問題 ( 当方,初心者です. )

はじめまして. 以下の問題を解くために自分でプログラムを書きました. 【 問題 】 ****************************************************** 図書館の目録管理用に,cardというクラスを作成せよ. このクラスに本のタイトルと著者,在庫数を格納します. タイトルと著者を文字列として保存し,在庫数を整数として保存します. store()という公開メンバ関数を使用して本情報を保存し, show()という公開メンバ関数により保存したデータを表示せよ. ****************************************************** しかしわからない点が1つあります. メンバ関数のstoreに文字列を渡すにはどうしたらよいでしょうか?? なお計算機環境は,VC++ver6.0をインストール済みのWin2000です. また,VCではWin32コンソールアプリケーションを利用して 以下のコードを書いています. ご指導お願いします. #include <iostream> using namespace std; // 名前空間. // クラスcardの定義. class card { char title; char author; int num; // 公開メンバ関数のプロトタイプ. public: void store(char title_name, char author_name, int zaiko_num); void show(); }; // メンバ関数の定義. // データ記録用. void card::store(char title_name, char author_name, int zaiko_num) { title = title_name; author = author_name; num = zaiko_num; } // メンバ関数の定義. // データ表示用. void card::show() { cout << title << endl; cout << author << endl; cout << num << endl; }; int main(int argc, char* argv[]) { // クラスオブジェクトの作成. card cd; // メンバ関数の参照. cd.store('C','U',20); cd.show(); return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • selenity
  • ベストアンサー率41% (324/772)
回答No.2

> となるのですか? そうです。 ある関数が「文字列」を受け取るにはchar *valueという形で受け取ります。 このような値の渡し型を「参照渡し(Call By Reference)」と言います。 この場合、関数内で受け取ったchar *valueに対して何かの操作すると、呼び出し元の変数の値(つまり文字列の実体の方)が変更されます。

kakaomame00
質問者

お礼

ふむ,もう一度C言語の本をひっくり返して復習します. 詳しい解説どうもありがとうございました. 今後もどうぞよろしくお願いいたします.

その他の回答 (2)

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.3

C++を使用しているのでしたら、stringクラスを使用されてはいかがでしょうか? stringクラスを使用してソースを書き直すと以下のようになります。 #include <iostream> #include <string> using namespace std; // 名前空間. // クラスcardの定義. class card { string title; string author; int num; // 公開メンバ関数のプロトタイプ. public: void store( string& title_name, string& author_name, int zaiko_num ); void show(); }; // メンバ関数の定義. // データ記録用. void card::store( string& title_name, string& author_name, int zaiko_num ) { title = title_name; author = author_name; num = zaiko_num; } // メンバ関数の定義. // データ表示用. void card::show() { cout << title << endl; cout << author << endl; cout << num << endl; }; int main(int argc, char* argv[]) { // クラスオブジェクトの作成. card cd; // 目録データの設定 string oTitle = "I, Robot"; string oAuther = "Asimov, Issac"; cd.store( oTitle, oAuther, 20 ); // 目録データの表示. cd.show(); return 0; }

kakaomame00
質問者

お礼

こんにちは.C++での実装法の解説ありがとうございます. 実際コードを書いて,その挙動を確認してみます. それでは失礼します.今後もよろしくお願いします.

  • selenity
  • ベストアンサー率41% (324/772)
回答No.1

まずは、基本を。 char 変数名; の変数には「1文字」しか格納できません。つまり「文字列」を格納することはできません。 「文字列」を格納するには「文字型の配列」または「文字型へのポインタ」を使う必要があります。 また、値の代入に関してはmemcpyやstrcpyを使います。 単純な代入では挙動不審になります。 また、コピー先の変数には、予め十分な容量が確保されている必要があります。

kakaomame00
質問者

補足

さっそく解説していただき有り難うございます. C++というよりはCの基本がわかっていませんでした. つまり,引数としては, 公開メンバ関数 store()の引数で, 文字列を渡す場合は,たとえば,char *dataとすべきということで 理解してよろしいでしょうか? すなわち,上のコードに準拠してかけば, void store::card( char *title_name , char *author_name, int zaiko_num) { // 関数定義内容. } となるのですか?

関連するQ&A

  • 下記、プログラム内の「char *」の役割

    C++初心者です。 縦長になってしまいますが、 『 #include <iostream.h> void show(int); void show(double); void show(char *);   ←左記の記述の使い方 int main(void) { show(1); show(0.25); show("文字列"); return 0; } void show(int x) { cout << x << endl; } void show(double y) { cout << y << endl; } void show(char *z) { cout << z << endl; } 』 のプログラムにおいて、「char *」の使い方がいまいち理解できません。 上記プログラムですとエラーが表示されないのですが、下記のプログラムだとエラーが発生します。 『 #include <iostream.h> void show(int); void show(double); void show(char);   //←---------上記と違う行 int main(void) { show(1); show(0.25); show("文字列"); return 0; } void show(int x) { cout << x << endl; } void show(double y) { cout << y << endl; } void show(char z) {  //←---------上記と違う行 cout << z << endl; } 』 なぜ、ポインタ(*)を付けないといけないのか分かりやすく教えていただけましょうか。

  • C++ 静的クラスの役割が分からない

    こんばんは。 C++で静的オブジェクトがなんなのか試しにプログラミングしているんですが どんな役割があるのか試してもよく分かりません。 static class HOGE { public: int *hoge; private: int value[2]; char moji[6]; public: HOGE() { cout << "HOGE\n"; } void MOJI() { strcpy(moji, "MOJI\n"); } void TEST() { cout << "moji = " << moji << endl; } static void staticMOJI() { } }sObj; sObjからは静的メンバ関数と静的メンバ変数は呼び出せるようです。他は呼び出せません。 そのようにするためにstatic宣言をするものなのでしょうか? このsObjからメンバ変数(*hoge)を呼び出すことは無理なんでしょうか?

  • C++のポインタの動作を教えてください

    ちょっと長いですが、ある部分の動作がわかりません そこを詳しく教えてください。 void queue::store(int i)の//リスト末尾に置くっていうところからで なぜ、if(tail)tail->next=item; tail=item; こう書くのかわからないです。 tail->next=itemの次にtail=itemを実行すると、tail->nextの内容も変わるのでは?と思っているのですがどうなっているのかわからないのでお願いします。 説明が下手ですがすみませんが教えてください。 //仮想関数の実例 #include <iostream> #include <cstdlib> #include <cctype> using namespace std; class list{ public: list *head; //リスト先頭へのポインタ list *tail; //リスと末尾へのポインタ list *next; //次項目へのポインタ int num; //格納される値 list(){ head=tail=next=NULL; } virtual void store(int i)=0; virtual int retrieve()=0; }; //キュー型リストの作成 class queue:public list{ public: void store(int i); int retrieve(); }; void queue::store(int i) { list *item; item=new queue; if(!item){ cout << "メモリ割り当てエラー" << endl; exit(1); } item->num=i; //リスト末尾に置く if(tail)tail->next=item; tail=item; item->next=NULL; if(!head)head=tail; } int queue::retrieve() { int i; list *p; if(!head){ cout << "リストは空です" << endl; return 0; } //リスト先頭から取り除く i=head->num; p=head; head=head->next; delete p; return i; } //スタック型リストの作成 class stack:public list{ public: void store(int i); int retrieve(); }; void stack::store(int i) { list *item; item=new stack; if(!item){ cout << "メモリ割り当てエラー" << endl; exit(1); } item->num=i; //スタックのような操作になるよう、リスト最前部におく if(head)item->next=head; head=item; if(!tail)tail=head; } int stack::retrieve() { int i; list *p; if(!head){ cout << "リストは空です" << endl; return 0; } //リスト先頭から取り除く i=head->num; p=head; head=head->next; delete p; return i; } class sorted:public list{ public: void store(int i); int retrieve(); }; void sorted::store(int i) { list *item; list *p,*p2; item=new sorted; if(!item){ cout << "メモリ割り当てエラー" << endl; exit(1); } item->num=i; //次項目のおき場所を見つける p=head; p2=NULL; while(p){ //中へ if(p->num>i){ item->next=p; if(p2)p2->next=item; //先頭要素ではない if(p==head)head=item; //新しい先頭要素 break; } p2=p; p=p->next; } if(!p){ //終わりへ if(tail)tail->next=item; tail=item; item->next=NULL; } if(!head)//先頭要素 head=item; } int sorted::retrieve() { int i; list *p; if(!head){ cout << "リストは空です" << endl; return 0; } //リスト先頭から取り除く i=head->num; p=head; head=head->next; delete p; return i; } int main() { list *p; //キューのデモ queue q_ob; p=&q_ob; //キューをさす p->store(1); p->store(2); p->store(3); cout << "キュー:"; cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << endl; //スタックのデモ stack s_ob; p=&s_ob; //スタックをさす p->store(1); p->store(2); p->store(3); cout << "スタック:"; cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << endl; //ソート済みリストのデモ sorted sorted_ob; p=&sorted_ob; p->store(4); p->store(1); p->store(3); p->store(9); p->store(5); cout << "ソ\ート:"; cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << endl; return 0; }

  • [C++]値の引渡しについて。

    教えて下さい。 mainの中においてasctimeで現在の日付を所得します。 その中の年だけをclassに渡し、classの中のメンバ関数で 使いたいのですが、mainからclassへはどう引き渡せばいいでしょうか? 汚いプログラムで申し訳ないのですが、mainのtm_yearの値を うるう年判定の関数で使いたいのです。 #include <iostream> #include<time.h> using namespace std; class TDate { public: int dt_month; int dt_day; int dt_year; bool leapYear; int year1; TDate(int month, int day, int year); void Display(); void Leap(); /*うるう年判定の関数*/ }; int main() { TDate dt_obj(11,1,2005); dt_obj.Display(); dt_obj.Leap(); struct tm *newtime; time_t aclock; char *now; time(&aclock); /* 現在時刻の獲得 */ newtime = localtime(&aclock); /* tm構造体への変換 */ now = asctime(newtime); /* 文字列への変換 */ cout << "現在の時刻" << now << endl; cout << "YEAR" << newtime -> tm_year << endl; return 0; } TDate::TDate(int month, int day, int year) { dt_month = month; dt_day = day; dt_year = year; } void TDate::Display() { cout << dt_month << "/" << dt_day << "/" << dt_year << endl; } void TDate::Leap() { year1 = n+1900; if ( year1 <= 0) cout << " Wrong year : Greater or equal to 0 " << endl; else { if ((year1 % 100) == 0 ) leapYear = ((year1 % 400) == 0 ); else leapYear = ((year1 % 4) == 0 ); if (leapYear) cout << year1 << " is a leap year " << endl; else cout << year1 << "is not a leap year" << endl; } } よろしくお願いします。

  • C++ 動的確保について

    学校の演習課題で「クラス Array のメンバ変数を以下のように変更して,配列のサイズを実行時に決められるようにしたい.コンストラクタを適切に修正しなさい.配列のサイズはコンストラクタの引数で指定できるようにすること.main 関数内のオブジェクトの宣言部分を適当に変更して動作を確認しなさい.」という課題が出ました。 指示のメンバ変数の変更は、sizeを定数にしていたものを変数にし、arrayを配列からポインタにする点です。 もとのプログラムはI、私がいじったものがIIです。どうにもセグメンテーションフォルトから抜け出せなくて困っています。どのようにしたら題意のプログラムになるのでしょうか? よろしくお願いします。 ここからI~ #include <iostream> using namespace std; class Array{ private: const static int size = 6; int array[size]; public: Array( ); int getSize( ); void put( int index, int data ); int get( int index ); void show( ); }; Array::Array( ) { for ( int i = 0; i < size; i++ ) { array[i] = 0; } } int Array::getSize( ) { return size; } void Array::put( int index, int data ) { array[index] = data; } int Array::get( int index ) { return array[index]; } void Array::show( ) { cout << "| "; for ( int i = 0; i < getSize( ); i++ ) { cout << get(i) << " | "; } cout << endl; } int main( ) { Array array1; array1.put(1, 2); array1.put(4, 1); array1.show( ); return 0; } ~ここまでI ここからII~ #include <iostream> using namespace std; class Array{ private: int size; int *array; public: Array(int s); ~Array(); int getSize(); void put(int index, int data); int get(int index); void show(); }; Array::Array(int s) { size = s; array = new int; for (int i = 0; i < size; i++) { *array = 0; array++; } array -= size; } Array::~Array() { delete[] array; cout << "デストラクタが呼ばれました。配列の要素数分のメモリを開放します." << endl; } int Array::getSize() { return size; } void Array::put(int index, int data) { *(array + index) = data; } int Array::get(int index) { return *(array + index); } void Array::show() { cout << endl << "| "; for (int i = 0; i < getSize(); i++) { cout << get(i) << " | "; } cout << endl; } int main() { int s = 0; cout << "確保するサイズを入力してください:"; cin >> s; Array array1(s); array1.put(1, 2); array1.put(4, 1); array1.show(); return 0; } ~ここまでII

  • c++ で *の逆三角旗を作りたいです

    普通の三角旗はできましたが逆三角旗が分かりません 例えば3と入力したら * ** *** ** * こんな感じで出力させたいのですが考え方が分かりません 普通の方のコードはこんな感じです int i, j; cin>>num; for (i = 1;i <= num;++i) { for (j=1;j<=i;j++) { cout << "*"; } cout << endl; } for (i = 1;i <= num-1 ;i++) { for (j=1;j<=num-i;j++) { cout << "*"; } cout << endl; } cout << endl;

  • C言語 初心者です。

    いつもお世話になっています。 またまた困ってます。 以下のソースは一部分を抜粋したものです。 質問内容ですが、現在コンパイルをすると、warningが出てきて、型の互換性がありません。とでてきます。たぶん文字列の長さを読むときがおかしいみたいで、型を色々変えましたが、warningはとれません。どうしたらいいか教えてください。 ちなみに #define NAME 128 /* IDの桁数 */ typedef struct { char name[NAME]; /* 社員番号 */ } syain; size_t str_length(char *str) { size_t length = 0; while (*str++){ length++; } return(length); } void namecheck(syain data[], int syain_num) { int len = 0;/* 社員名の桁数 */ while(1){ printf("社員名:"); scanf("%s", data[syain_num].name); /* 社員名の桁数を変数lenに格納する */ len =(unsigned)str_length(data[syain_num].name); putchar('\n'); if (len < NAME){ break; } } } void syaintouroku(syain data[], int syain_num) { namecheck(data[syain_num].name, syain_num); putchar('\n'); } int main(void) { syain meibo[MAX_NUMBER]; int max_syain = 0; int i; syaintouroku(meibo, max_syain); max_syain++; return (0); }

  • C++勉強中なんですが

    クラス等を使ってソースを書く練習中なのですが、思ったように結果が出ません。 #include<iostream> #include<string> using namespace std; class Cats { private://クラス「Cats」の中でのみ使う文字列の入れ物変数「name」を作る string name; public://クラス「Cats」の外からでも引数で呼び出せば使える Cats(string x)//クラスCatsの関数Cats(コンストラクタ)を使いますよって宣言 { name=x;//8行目で作った文字列の入れ物に変数xを入れる } void naku()//voidの意味が正確には分からないけど、何も返さないって意味らしいので、何も返さないnakuって関数を作る { cout<<"にゃっふぅーん、ボク、"<<name<<"ってゆーの。よろしくネ!"<<endl;//関数nakuが呼び出されると文字列を表示する } }; int main()//全体のプログラム { string x;//まず文字列の入れ物になる変数xを作る cout<<"今日新たな家族になるにゃんこが産まれました。"<<endl; cout<<"名前を決めてあげましょう!"<<endl; Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x) cin>> x;//変数xにキーボードで書いた文字列を入れる aisatsu.naku();//メンバー関数のaisatsuがグローバル関数(クラスの外からでも呼べるはずw)nakuを呼び出す } cin>>x;で入力した文字がnameに代入されてないのか、表示されません・・・。 もし分かる方いたら是非教えていただきたいです。 あと、コメントアウトしてる部分なんですが、ここもおかしい認識があればご指摘いただきたいです。

  • デストラクタについて

    #include <iostream> #include <string> using namespace std; #define NUM 2 //登録人数 class Person{ char *name; int *age; char *hobby; public: Person() { name = new char; age = new int; hobby= new char; } void Set(char *n,int a,char *h) { name=n; *age=a; hobby=h; } char *Get_name(void) { return name; } int Get_age(void) { return *age; } char *Get_hobby(void) { return hobby; } ~Person() { cout<<name<<"のデストラクタ\n"; delete [] name; delete age; delete [] hobby; } }; int main(void) { Person *p; int i; p=new Person[NUM]; p[0].Set("永嶋",21,"映画鑑賞"); p[1].Set("平林",54,"車"); for(i=0;i<NUM;i++){ cout<<"\n名前:"<<p[i].Get_name(); cout<<"\n年齢:"<<p[i].Get_age(); cout<<"\n趣味:"<<p[i].Get_hobby()<<"\n"; } delete [] p; return 0; } というプログラムを作成したのですが デストラクタの3つのdeleteがおかしいようなのですが どのような部分が問題となっているのでしょうか? 回答・アドバイス宜しくお願いいたします。

  • メンバ関数の引数としてオブジェクトの配列をとれる?

    VC++6.0 on W2Kを使っている初心者です。 表題のとおりですが、具体的なプログラムは下のようです。 また、*部分に相当するところもエラーになるのですが、 どのように変えればよいのでしょうか? なお、プログラムの内容そのものには意味はなく 単に動作確認のためのサンプルです。 実行すると、 「How many cats do you create?」 と聞かれるので、数字を入力すると、 Nekoオブジェクトが生成され、i番目の猫にはiという名が付けられます。 そして、「何匹目を鳴かせますか?」と聞かれるので、 数字を入力すると、 「My name is i-th cat.」 と答えられ、さらに、Inuが、 「i-th cat is tasty.」 と答える、という内容になっています。 #include <iostream> #include <string> using namespace std; class Neko { int name; public: Neko(){} Neko(int n):name(n){} void setname(int n){name=n;} int getname(){return name;} void naku(int n) const; }; void Neko::naku(int i) const { cout <<"My name is "<<getname()<<"th cat."<<endl;・・・* } class Inu { public: Inu(){} void naku(int i) const; }; void Inu::naku(int i)const{ cout <<i<<"th cat is tasty."<<endl; } int main() { int i; int num; int temp; Neko *x; Inu y; cout <<"How many cats do you create?"<<endl; cin >>num; x=new Neko[num]; for(i=0;i<num;i++){ x[i].setname(i); } cout <<"何匹目を鳴かせますか?"<<endl; cin >> temp; x[temp].naku(); y.naku(temp); }

専門家に質問してみよう