Converting cin>>string to an int pointer?

Have been looking at structs, arrays, pointers, maps, templates, vectors, and sets. I am completely lost on how to getline from a user and convert that to an integer pointer that points to a character array of item descriptions from a struct. I'm trying to create a text based game. I have looked at multiple books and through all the Cplusplus tutorials. I am new to C++ and slow in realizing concepts, however no matter what I try I always get an error that Codeblocks doesn't have 2011 code (-std=c++11). I do not want to have endless arrays pointing to endless arrays, as my final program (hopefully), will have many items. I am aware that the below code does not compile. Any help will be appreciated, thanks.

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
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <set>
#include <map>
using namespace std;
struct Items
{
    char item_name[50];
    char item_desc[999];
    int item_number;
};
int main()
{
    struct Items hammer;
    struct Items nail;
    struct Items wrench;

    strcpy( hammer.item_name, "Bob's Hammer");
    strcpy( hammer.item_desc, "This is Bob's trusty, tried, and true hammer.");
    hammer.item_number = 1;

    strcpy( nail.item_name, "Nail");
    strcpy( nail.item_desc, "A regular iron nail.");
    nail.item_number = 2;

    strcpy( wrench.item_name, "Wrench");
    strcpy( wrench.item_desc, "This is Bob's socket wrench.");
    wrench.item_number = 3;

string Itemarray[3] { hammer.item_desc, nail.item_desc, wrench.item_desc };
cout << "Which item would you like to look at?" << endl;
int *line;
*line = &Itemarray[3];
cin >> *line;
cout << *line <<endl;
    return 0;
}
you use C++ so you should std::string instead of char arrays.

Furthermore, you overthink this ...
You want to just enter a number n and get the item on index n, right?
Just save it as int and access the n-th element of itemarray.

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
#include <string>
#include <iostream>

struct Items
{
    std::string item_name;
    std::string item_desc;
    int item_number;
};
int main()
{
    // struct keyword not needed in C++
    Items hammer;
    Items nail;
    Items wrench;

    hammer.item_name = "Bob's Hammer";
    hammer.item_desc = "This is Bob's trusty, tried, and true hammer.";
    hammer.item_number = 1;

    nail.item_name = "Nail";
    nail.item_desc = "A regular iron nail.";
    nail.item_number = 2;

    wrench.item_name = "Wrench";
    wrench.item_desc = "This is Bob's socket wrench.";
    wrench.item_number = 3;

    std::string Itemarray[3] { hammer.item_desc, nail.item_desc, wrench.item_desc };
    std::cout << "Which item would you like to look at? [0-2]" << std::endl;
    int item;
    std::cin >> item;
    std::cout << Itemarray[item] <<endl;

    return 0;
}
Last edited on
@Gamer2015

Your code is missing either using namespace std; or assorted std:: qualifiers.

And itemarray isn't the same as Itemarray

(And the item extraction is not checked to see if it was valid, nor is the index obtained checked to see if it's in range.)

Andy

PS I'm not a fan of unguarded cin >> <an int variable> usage. As the program stands (with the above fixes):

Which item would you like to look at? [0-2]
whatever
This is Bob's trusty, tried, and true hammer.

And entering 666 crashes it!

The following code is a backported (to C++03) and de-templated version of cire's code here:

Trying to limit input to int type
http://www.cplusplus.com/forum/beginner/108849/#msg592118

and shows how to safely obtain an int value (the topic has been discusses time after time; I just happen to like cire's take!)

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
#include <sstream>
#include <string>
#include <iostream>
using namespace std;

// validate is a function pointer to a function of the form
// bool function_name(const int&);
int get(const std::string& prompt, bool(* validate)(const int&))
{
    int result = 0;

    bool notDone = true;

    while (notDone)
    {
        std::cout << prompt ;

        std::string line;
        std::getline(std::cin, line);

        std::istringstream is(line);

        // First we attempt to extract an int from the streem
        // if successful, we jump all whitespce (using std::ws) and then try
        // to get a char. If that's successful we were given a string with chars
        // after the int, e.g. "67kg" or "99 red balloons".
        char dummy;
        if (!(is >> result) || (is >> std::ws && is.get(dummy)) || !validate(result))
            std::cout << "Invalid input. Try again!\n";
        else
            notDone = false ;
    }

    return result;
}

// validate function for int between 1 and 100
bool check_value(const int& val)
{
    return val > 0 && val < 101;
}

int main()
{
    const char msg[] = "Enter a number between 1 and 100 and I will guess it: ";

    int playerNumber = get(msg, check_value);

    std::cout << playerNumber << '\n';

    return 0;
}


Last edited on
I always get an error that Codeblocks doesn't have 2011 code (-std=c++11).

Which version of Code::Blocks are you using?

I see from Code::Blocks download page that their current stable release for Windows uses MinGW GCC version 4.7.1. This version of the compiler should understand -std=c++11

Before C++11 was released, the GCC compiler did support some C++11 features if you passed -std=c++0x on the command line.

Do you know what version of GCC you are using? (Use 'gcc --version' or 'g++ version' from a console/command line/terminal which can see the compiler.)

Andy
Last edited on
@andywestken
If the compiler talks about -std=c++11 it probably knows how to handle it.

@OP
The compiler is telling you that to use C++11 features you should enable C++11 by passing the -std=c++11 flag to the compiler. Since you are using Code::Blocks (and not compiling from the command) you should be able to find where to enable C++11 features in the settings somewhere. I'm not saying you necessary need it in this program.
Last edited on
You do realise that line 40 makes absolutely no sense.

37
38
39
40
41
42
string Itemarray[3] { hammer.item_desc, nail.item_desc, wrench.item_desc };
cout << "Which item would you like to look at?" << endl;
int *line;
*line = &Itemarray[3];
cin >> *line;
cout << *line <<endl;

1. you integer pointer is uninitialized, so dereferencing it has a very good chance of blowing up; if not, you be setting some random bit of memory to an int value.

2. you're trying to set the value of the integer supposedly pointed to by your int* to the address of a row of a string array (which will be a string*)

3. the index you're using is the same size as the array, so it's referring to the element just beyond the extent of the array, which will either be junk or part of some other variable. Or cause the program to crash.

And that line 41 and 42 just read an int value and write it back out (if the pointer was referring to a valid memory address, that is.)

Being really perverse, this will compile

37
38
39
40
41
42
43
44
45
    string Itemarray[3] { hammer.item_desc, nail.item_desc, wrench.item_desc };
    cout << "Which item would you like to look at?" << endl;
    int temp = 0; // somewhere to store int
    int *index = &temp; // point at an existing int
    //*line = &Itemarray[3];
    cin >> *index; // should be checking this works!
    string *line;
    line = &Itemarray[*index]; // line not *line, and *index replaces 3
    cout << *line <<endl;

But not that line 37 is actually using a C++11 feature, so if this works for you your compiler must have partial support at least for C++11.

Eliminating the pointless int* (it's only ever used by dereferencing it) and replacing string* with a reference, you get (basically the same as approach as Gamer2015 used):

37
38
39
40
41
42
    string Itemarray[3] { hammer.item_desc, nail.item_desc, wrench.item_desc };
    cout << "Which item would you like to look at?" << endl;
    int index = 0;
    cin >> index; // should be checking this works!
    string& line = Itemarray[index]; // should be checking index in range
    cout << line <<endl;

Of course, as I've already said, the index shouldn't be used without validation. Esp. in something like a game!

Andy
Last edited on
You code does look very C to me, so pushing it to (old-school) C89 I get:

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
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct Items
{
    char item_name[50];
    char item_desc[999];
    int item_number;
};
int main()
{
    struct Items Itemarray[3];
    int index = 0;
    char* line = NULL;

    strcpy( Itemarray[0].item_name, "Bob's Hammer");
    strcpy( Itemarray[0].item_desc, "This is Bob's trusty, tried, and true hammer.");
    Itemarray[0].item_number = 1;

    strcpy( Itemarray[1].item_name, "Nail");
    strcpy( Itemarray[1].item_desc, "A regular iron nail.");
    Itemarray[1].item_number = 2;

    strcpy( Itemarray[2].item_name, "Wrench");
    strcpy( Itemarray[2].item_desc, "This is Bob's socket wrench.");
    Itemarray[2].item_number = 3;

    printf("Which item would you like to look at?\n");
    scanf("%d", &index); // should be checking this works!
    line = Itemarray[index].item_desc;
    printf("%s\n", line);
    return 0;
}

I didn't see the need for the separate arrays (hammer, nail, wrench) so just used Itemarray from the get go (but not an array of struct Items rather than of string)

Or in C-like C++

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
#include <iostream>
#include <string>
using namespace std;
struct Items
{
    string item_name;
    string item_desc;
    int item_number;
};
int main()
{
    Items Itemarray[3];

    Itemarray[0].item_name = "Bob's Hammer";
    Itemarray[0].item_desc = "This is Bob's trusty, tried, and true hammer.";
    Itemarray[0].item_number = 1;

    Itemarray[1].item_name = "Nail";
    Itemarray[1].item_desc = "A regular iron nail.";
    Itemarray[1].item_number = 2;

    Itemarray[2].item_name = "Wrench";
    Itemarray[2].item_desc = "This is Bob's socket wrench.";
    Itemarray[2].item_number = 3;

    cout << "Which item would you like to look at?" << endl;
    int index = 0;
    cin >> index; // should be checking this works!
    string& line = Itemarray[index].item_desc; // should be checking index in range
    cout << line <<endl;
    cout << line <<endl;
    return 0;
}

which is more or less back to Gamer2015's code.

But as you are planning to use a lot of items, aybe you should use a std::array rather than a C array. And aybe even load your items from a config file?

Andy
Last edited on
Peter87 wrote:
@andywestken
If the compiler talks about -std=c++11 it probably knows how to handle it.

Good point. I can't have correctly 'parsed' the sentence. :-/

Andy
Last edited on
Topic archived. No new replies allowed.