質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

Vectorクラスの配列へ文字列を代入する方法が知りたいです。

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 5,180

Kenny009

score 15

前提・実現したいこと

昨年末からネットや書籍でC++の勉強をしており、現在は動的配列の処理で困っています。
プログラミングビギナーです。
ネットや本で3日粘ってここまで来ましたが、動的配列に対して文字型や文字列の処理を扱っている例がなく、心が折れそうです。

目的としては名簿を作成したいです。
名簿への登録人数をコンストラクタで指定し、クラス関数で名前の入力、出力を実装したいです。

発生している問題・エラーメッセージ

30行目
error: no type named ‘type’ in ‘struct std::enable_if<false, std::basic_ostream<char>&>’

51行目
error: no match for ‘operator=’ (operand types are ‘gnu_cxx::alloc_traits<std::allocator<std::vector<char> > >::value_type {aka std::vector<char>}’ and ‘const char [7]’)

該当のソースコード

1 #include<iostream>
2 #include<stdio.h>   
3 #include<stdlib.h>   
4 #include<vector>   
5    
6 using namespace std;   
7    
8 class StudentList   
9 {  
10         private:  
11                 int a;  
12         public:  
13                 int num;  
14                 int b;                  
15                 vector<vector<char> >student;
16                 StudentList();
17                 int input_name(int b);
18                 int show_name(int c);
19 };
20 
21 StudentList::StudentList()
22 {
23         cout << "登録する人数を指定してください" << endl;
24         cin >> num;
25 }
26 
27 int StudentList::input_name(int b)
28 {
29         cout << b << "番目に登録する名前を入力して下さい" << endl;
30         cin >> student[b];
31 }
32 
33 int StudentList::show_name(int c)
34 {
35         if(c < num)
36         {
37                 cout << c << "番目の名前は" << student[c] << endl;
38         }
39         else
40         {
41                 cout << "欠番" << endl;
42         }
43 }
44 
45 int main(void)
46 {
47         StudentList list;
48         list.student.resize(10);
49         list.student[0].resize(15);
50 
51         list.student[0] = "名前";
52 
53         for(int i = 1;i<=list.num;i++)
54         {
55                 list.student[i].resize(15);
56                 list.input_name(i);
57         }
58
59         while(1)
60         {
61                 cout << "番号を入力して下さい" << endl;
62                 cout << list.b;
63                 if(list.b > list.num || list.b < 1)
64                 {
65                         cout << "番号は1以上かつ" << list.num << "以下" <<endl;
66                         break;
67                 }
68                 else
69                 {
70                         list.show_name(list.num);
71                 }
72         }
73         return 0;
74 }

c++

試したこと

strcpy(student[0],"名前");

補足情報(FW/ツールのバージョンなど)

VirtualBox
Ubunts(64bit)
コンパイラのバージョン,7

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • cateye

    2019/02/14 23:31 編集

    vector<vector<char> >student; ではなくstd::vector<std::string> student; では、だめですか?・・・あと、Cのヘッダを使っているのはなぜ?・・・<string>をインクルードするように・・

    キャンセル

回答 3

+6

型を std::vector<std::string> にするのが簡潔で扱いやすいかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/16 20:00

    その通りですね。なんでかcharにこだわっていました。
    ありがとうございます。

    キャンセル

+2

すでに、多くの方から指摘されているとおり、std::string を使用した方がよろしいとは思いますが、あえてこのまま実行できるように変更してみました。
まだ、見直すべき点はありますが、とりあえず最低限の修正です。

#include<iostream>
#include<stdio.h>   
#include<stdlib.h>   
#include<vector>   

using namespace std;

class StudentList
{
private:
    int a;
public:
    int num;
    int b;
    vector<vector<char> >student;
    StudentList();
    int input_name(int b);
    int show_name(int c);
};

StudentList::StudentList()
{
    cout << "登録する人数を指定してください" << endl;
    cin >> num;
}

int StudentList::input_name(int b)
{
    cout << b << "番目に登録する名前を入力して下さい" << endl;
    //cin >> student[b];
    cin >> &student[b][0];                //修正

    return 0;                            //???
}

int StudentList::show_name(int c)
{
    if (c < num)
    {
        //cout << c << "番目の名前は" << student[c] << endl;
        cout << c << "番目の名前は" << &student[c][0] << endl;
    } 
    else
    {
        cout << "欠番" << endl;
    }

    return 0;                            //???
}

int main(void)
{
    StudentList list;
    list.student.resize(10);
    list.student[0].resize(15);

    //list.student[0] = "名前";

    for (int i = 1; i <= list.num; i++)
    {
        list.student[i].resize(15);
        list.input_name(i);
    }

    while (1)
    {
        cout << "番号を入力して下さい" << endl;
        //cout << list.b;
        cin >> list.b;                    //修正
        if (list.b > list.num || list.b < 1)
        {
            cout << "番号は1以上かつ" << list.num << "以下" << endl;
            break;
        }
        else
        {
            //list.show_name(list.num);
            list.show_name(list.b);        //修正
        }
    }
    return 0;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/16 20:09

    皆様のご指摘通りstringに直しました。
    しかし、charでも出来るんですね。三日かけても自分は出来ませんでした。
    charの配列の場合、直接アドレスを読み書きすれば良かったんですね。
    考え方が勉強になりました。
    ありがとうございます。

    キャンセル

checkベストアンサー

+1

ちょっと ここ(teratail)の使い方が違いますよ。

他の回答者や質問者の書き方を参考にしてください。


まず、気になったのは、必ず vector<char>のvectorでないといけませんか?

単に文字列を使うなら std::string が(まだ)いいです。

char* とするとアドレスが確保されるようです。コツがいるので、

std::vector<std::string> strs;

みたいにやったほうがわかりやすいですし、使いやすいです。

また、StudentListクラスにあるnum, b, student はなるべくprivateに。

参考: オブジェクト指向設計 getter, setterを使うなとはどういうことか

また、もしかして日本語を入力していませんか? 特に student を入力させるところ。

日本語は基本的に全角文字です。

半角英数字なら 配列だと 一要素分 で済む場合でも、全角だと基本的に 二要素は必要です。( バイト数によって変わるのかな? ここはわからんが。 )

なので、単純に考えると、

"あいうえお" でも日本語的に考えると5文字。でも半角英数字と比較した場合は、単純計算で 5×2=10 となり、10文字扱いになります。(厳密にはバイト数だけど。)

ケータイサイズのケース( ケータイでもいいし、たばこでもいい。 ) に ノートパソコンを入れようとしているのと同じこと。
「え? 同じ人工物でしょ?」みたいな。


[追記1]

ちなみに日本語みたいな全角で一文字とするような文字で構成するなら std::stringよりは std::wstring がいいみたいです。

定義は忘れましたが、std::stringはcharの動的確保系ですが、std::wstring は wchar_t の動的確保系です。

日本向けに発送して、かつ、個人開発なら std::wstringのほうが無難...かな?

ちょっとコツが要りますが、std::wstringだと文字化けしにくいです。( ただしOSの設定とかによるかもしれないが。 )

std::stringだと、"あ" と構成するだけでも、1バイト目と2バイト目をチェックしてやっとわかる。

だから 1バイト目にそれだけで完結するデータが来たらそれで終了してしまう可能性がある。

文字コードはよくわからないので、あくまでイメージですが、

"さすが" と "d*pqが" が同じ...

みたいな感じで文字化けする可能性が高いです。

std::wstring だと wchar_t なので "あ" で一つ。と見なせるらしいので、日本語を扱うならこっちのほうが楽かな?

また、私はあまりわかりませんが、std::stringはバグを持っているっぽいです。
(どっかの記事で見かけた...どこだったっけ?)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/16 20:05

    >ちょっと ここ(teratail)の使い方が違いますよ。
    ご指摘通り他の回答者や質問者の書き方を参考にさせていただきます。

    >必ず vector<char>のvectorでないといけませんか?
    そんなことないです。
    文字列=char型の配列使わなきゃ。。。という思考になってました。

    >また、もしかして日本語を入力していませんか? 特に student を入力させるところ。
    はい。日本語にも対応させたいと思っています。なので、ご指摘通りメモリサイズに気を付けます。

    解答ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る