storing and displaying char in vectors

May 8, 2017 at 10:52am
As part of learning c++, rather than using std::string, i want to use char to store and display words. so I wrote a simple program.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
    int max = 10;
    std::vector<char> vec;
    
    for(int i=0;i<3;i++){
      
      char ch[max];
      std::cout<<"Enter your favorite color:";
      std::cin.getline(ch,max);
         
      vec.push_back(ch[max]);  
      std::cout<< ch <<"\n";
      std::cout<< vec[i] <<"\n";
      
    }


I am able to get the user input data and display it, but seem to have problem with storing the data in a vector and displaying the vector data within the same FOR loop. Rather than use iterators to display the vector data in a different FOR loop, i wanted to see if I could display the data within the same loop.


From what I read online, i have a feeling this might not be working due to std::vector<char> vec being neither assignable or copyable. Is that right ? or if I am mistaken, what is causing this problem and how can i use char to store words in a vector and display them within the same FOR loop?
May 8, 2017 at 11:33am
std::vector<char> stores char's i.e. each element is a single char – I suspect the favorite colors each run to more one char?

part of learning c++, rather than using std::string

why? Wouldn't you learn c++ best practices as it were?
May 8, 2017 at 11:39am
@gunnerfunner I understand the best practices idea. but i don't think it is impossible to use char and store data. I just want to be able to accomplish this. This will help me understand the limitations of each concept. and helps me understand the 'whys' about each command.
May 8, 2017 at 11:40am
From what I read online, i have a feeling this might not be working due to std::vector<char> vec being neither assignable or copyable. Is that right ?
That's wrong. It is actually both and also moveable.

What you're doing wrong is on line 10 using max as an index.

I don't see the use of a vector in this example...
May 8, 2017 at 12:10pm
@coder777 I want to implement a program using char,vector and 'words' (rather than individual letters).

My basic premise: The user is prompted for a word. The word is input into a char variable and stored in a vector.

I set out on this idea. If you think my example of a program is wrong. Could you help me come up with a simple program where I can implement all the three concepts.

If you think I'm being adamant, I hope you'll see that I'm doing this just to understand limitations of concepts and ideas.
May 8, 2017 at 1:20pm
 to std::vector<char> vec being neither assignable or copyable. Is that right ? or if I am mistaken, what is causing this problem

it's C-style arrays that are not copyable and assignable, so if you really want to use them try something on the following lines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <vector>

constexpr auto MAX = 10;

struct charNames
{
    char ch[MAX];
    charNames()
    {
        std::cout << "Enter favorite color \n";
        //size restrictions apply
        std::cin.getline(ch, MAX);
    }
};
std::ostream& operator << (std::ostream& os, const charNames& c)
{
    os << c.ch << "\n";
}

int main()
{
    std::vector<charNames> names{};

    for (size_t i = 0; i < 3; ++i)
    {
        names.emplace_back(charNames());
    }
    for (const auto& elem : names)std::cout << elem;
}

this is for learning but in actual programs prefer std::string
Last edited on May 8, 2017 at 1:21pm
May 8, 2017 at 1:32pm
@gunnerfunner

I've done the program with std::string. I got curious with the char option. i believe to get to where you are, I need to try different ways of implementing stuff rather do stuff just one way. Hence this idea.

And thank you for approach. This is closer to what I wanted to do. I just have to rack my brains to come up with different ideas to learn more.
May 8, 2017 at 2:24pm
> As part of learning c++, rather than using std::string ...

The stream extraction operator (deliberately) does not use an auxiliary std::string;
there should be a few things to learn from studying it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
#include <vector>

std::vector<char> make_vec_str( const char* cstr )
{
    if(cstr)
    {
        const char* end = cstr ;
        while( *end++ ) ;
        return { cstr, end } ;
    }

    else return {} ;
}

std::istream& operator >> ( std::istream& stm, std::vector<char>& vec_str )
{
    vec_str.clear() ;

    const auto& ctype = std::use_facet< std::ctype<char> > ( stm.getloc() ) ;
    char c ;

    // extract and discard leading white space
    while( std::char_traits<char>::not_eof( stm.peek() ) &&
           ctype.is( std::ctype_base::space, stm.peek() ) ) stm.get(c) ;

    // append characters till the first white space character
    while( stm.get(c) && !ctype.is( std::ctype_base::space, c ) ) vec_str.push_back(c) ;

    // put back the last white space extracted (if any)
    if( !vec_str.empty() ) stm.putback(c) ;

    return stm ;
}

// TO DO: getline

std::ostream& operator << ( std::ostream& stm, const std::vector<char>& vec_str )
{
    for( char c : vec_str ) stm << c ;
    return stm ;
}

int stoi( const std::vector<char>& vec_str, std::size_t* pos = 0, int base = 10 )
{ return std::stoi( std::string{ std::begin(vec_str), std::end(vec_str) }, pos, base ) ; }

// TO Do: other string operations

int main()
{
    std::vector<char> first, second, third ;

    std::cin >> first >> second >> third ;

    std::cout << " first: " << first << '\n'
              << "second: " << second << '\n'
              << " third: " << third << '\n' ;

    if( first == second ) std::cout << "first == second\n" ;
    if( second > third ) std::cout << "second > third\n" ;

    const std::vector<char> vec_str = make_vec_str( "123456" ) ;
    std::cout << stoi(vec_str) + 7'000'000 << '\n' ;
}

http://coliru.stacked-crooked.com/a/460b00c3a206baaf
May 8, 2017 at 2:58pm
To organize words just with vectors you may use vector of vectors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    int max = 10;
    std::vector<std::vector<char> > vec; // The inner vector is the word.
    
    for(int i=0;i<3;i++){
      
      vec.emplace_back(max); // This creates an instance of the inner vector with 'max' char
      std::cout<<"Enter your favorite color:";
      std::cin.getline(vec.back().data(),max); // This gets the data of the previously created vector
         
      vec.push_back(ch[max]);  // This is not needed
      std::cout<< ch <<"\n";
      std::cout<< vec[i].data() <<"\n"; // Accessing the data of the inner vector which contains the c-string
      
    }
May 8, 2017 at 4:05pm
@JLBorges This sure is a lot to process. But this is wanted. To study different approaches to get me to understand concepts better. Thank you,


@coder777 Here is something I learnt today. The benefits of using vectors/struct within vectors . Thank you .
Topic archived. No new replies allowed.