ページ 11

C++

Posted: 2016年9月07日(水) 21:16
by apple

コード:

#include<stdio.h> 
#pragma warning(disable:4996)

class CTest
{
private:
char name[20];
int atk;
int def;
int suu;
public:
CTest(void); //コンストラクタ
~CTest(void); //デストラクタ
void input_data(void);
void output_data(void);
void count(void);
};

CTest::CTest(void){
printf("コンストラクタ\n");
}

CTest::~CTest(void){
printf("\nデストラクタ\n");
}

void CTest::count(void){
printf("\n人数入力==>");
scanf("%d", &suu);
}

void CTest::input_data(void){
for (int i = 0; i < suu; i++){
printf("\n%d人目\n名前==>",i+1);
scanf("%s", &name);
printf("攻撃力==>");
scanf("%d", &atk);
printf("防御力==>");
scanf("%d", &def);
}
}

void CTest::output_data(void){
for (int i = 0; i < suu; i++){
printf("\n%d人目\n名前:%s\n",i+1, name);
printf("攻撃力:%d\n", atk);
printf("防御力:%d\n", def);
}
}

int main(void){
CTest* Obj;
Obj = new CTest; //Obj=new CTest[10];
Obj->count();
Obj->input_data();
Obj->output_data();
delete Obj;
return 0;
}

人数を入力して、その人数分の名前・攻撃力・防御力を入力して、人数分出力したいのですが
最後に入力した名前・攻撃力・防御力が人数分出力されてしまいます。
人数分の名前・攻撃力・防御力が正しく出力されるプログラムを教えて下さい。
構造体は使わないでお願いします。

Re: C++

Posted: 2016年9月07日(水) 21:39
by みけCAT
人数分の名前・攻撃力・防御力を正しく出力するには、人数分の名前・攻撃力・防御力を正しく保存しないといけません。

コード:

#include<stdio.h> 
#pragma warning(disable:4996)

class CTest
{
    private:
    char (*name)[20];
    int *atk;
    int *def;
    int suu;
    public:
    CTest(void); //コンストラクタ
    ~CTest(void); //デストラクタ
    void input_data(void);
    void output_data(void);
    void count(void);
};

CTest::CTest(void){
    printf("コンストラクタ\n");
    name = NULL;
    atk = NULL;
    def = NULL;
}

CTest::~CTest(void){
    printf("\nデストラクタ\n");
    delete[] name;
    delete[] atk;
    delete[] def;
}

void CTest::count(void){
    printf("\n人数入力==>");
    scanf("%d", &suu);
    delete[] name;
    delete[] atk;
    delete[] def;
    name = new char[suu][20];
    atk = new int[suu];
    def = new int[suu];
}

void CTest::input_data(void){
    for (int i = 0; i < suu; i++){
        printf("\n%d人目\n名前==>",i+1);
        scanf("%s", name[i]);
        printf("攻撃力==>");
        scanf("%d", &atk[i]);
        printf("防御力==>");
        scanf("%d", &def[i]);
    }
}

void CTest::output_data(void){
    for (int i = 0; i < suu; i++){
        printf("\n%d人目\n名前:%s\n",i+1, name[i]);
        printf("攻撃力:%d\n", atk[i]);
        printf("防御力:%d\n", def[i]);
    }
}

int main(void){
    CTest* Obj;
    Obj = new CTest;
    Obj->count();
    Obj->input_data();
    Obj->output_data();
    delete Obj;
    return 0;
}
このコードでは省略しましたが、ポインタを扱うのでコピーコンストラクタや代入演算子を明示的に定義した方が安全です。
(明示的に定義しないと、インスタンスをコピーした時にポインタが指すバッファではなくポインタの値のみがコピーされ、二重開放などの問題が生じることがあります)

Re: C++

Posted: 2016年9月07日(水) 21:43
by みけCAT
生の配列ではなく、STLのコンテナを使う方法もあります。

コード:

#include<cstdio>
#include<vector>
#include<string>
#pragma warning(disable:4996)

class CTest
{
    private:
    std::vector<std::string> name;
    std::vector<int> atk;
    std::vector<int> def;
    int suu;
    public:
    CTest(void); //コンストラクタ
    ~CTest(void); //デストラクタ
    void input_data(void);
    void output_data(void);
    void count(void);
};

CTest::CTest(void){
    printf("コンストラクタ\n");
}

CTest::~CTest(void){
    printf("\nデストラクタ\n");
}

void CTest::count(void){
    printf("\n人数入力==>");
    scanf("%d", &suu);
    name.resize(suu);
    atk.resize(suu);
    def.resize(suu);
}

void CTest::input_data(void){
    for (int i = 0; i < suu; i++){
        char name_buf[20];
        printf("\n%d人目\n名前==>",i+1);
        scanf("%19s", name_buf);
        name[i] = name_buf;
        printf("攻撃力==>");
        scanf("%d", &atk[i]);
        printf("防御力==>");
        scanf("%d", &def[i]);
    }
}

void CTest::output_data(void){
    for (int i = 0; i < suu; i++){
        printf("\n%d人目\n名前:%s\n",i+1, name[i].c_str());
        printf("攻撃力:%d\n", atk[i]);
        printf("防御力:%d\n", def[i]);
    }
}

int main(void){
    CTest* Obj;
    Obj = new CTest;
    Obj->count();
    Obj->input_data();
    Obj->output_data();
    delete Obj;
    return 0;
}