Asking a User for Addresses in Arrays

I am trying to create an array called block that holds 3 addresses. I need to ask the user for the three addresses. Would I need an enum class before the
struct and array in order to pull the information into the array and create
a cout and cin for the address information? I'm so lost. Here is what I have so far:

#include <iostream>
#include <string>
#include <array>


struct Block
{
int streetNumber;
std::string street;
std::string city;
std::string state;
int zipcode;

};


int main()
{
std::array<Block, 5> address{ };
{
Block.at(0);
Block.at(1);
Block.at(2);
Block.at(3);
Block.at(4);
}

return 0;

)

Here is my new code. The first address works fine, but after the requests for both addresses pops up at the same time and i can't input the information:

#include <iostream>
#include <string>
#include <array>


struct Address
{
int streetNumber{};
std::string street{};
std::string city{};
std::string state{};
int zipcode{};

};


int main()
{
std::array<Address, 5> address{ };
{
std::cout << "Enter your primary address: \n";
std::cin >> address.at(0).streetNumber >> address.at(1).street >> address.at(2).city >> address.at(3).state >> address.at(4).zipcode;


std::cout << "Enter your secondary address: \n";
std::cin>> address.at(0).streetNumber >> address.at(1).street >> address.at(2).city >> address.at(3).state >> address.at(4).zipcode;


std::cout << "Enter an alternative address: \n";
std::cin>> address.at(0).streetNumber >> address.at(1).street >> address.at(2).city >> address.at(3).state >> address.at(4).zipcode;

}

return 0;
}

Last edited on
I do not like the enum class; it locks out the one thing enum did well.
.at is safe but much slower than []. Won't matter here, but keep it in mind.

that said ... you have an array of structs. A user will presumably interact with one struct, their own address(?) (its possible to have multiple addresses but is that what you need?)

I don't think you need an enum...
something like..
unsigned int usernum{};
cin >> usernum;
if(usernum >4) cout <<"bad user\n";
else
{
do something with address[usernum].fields
}

note that block is not the array, block is the type of the struct. your array is 'address' and it is an array of the block struct type, with 5 cells.

the only use for an enum here, then, would be to name the addreseses.
eg
enum addresstypes{home,work,mailing,alternate1, alternate2, addr_max};
..
cout enter mailing address info..
cin address[mailing].zipcode //whatever [mailing] is more readable than [2]
here usernum becomes a choice and that choice tells you which enum to use, but that is silly for so small a program, you can just access using the number the user put in. If you needed to map their user number from something else (say, their govt ID number) to 0-4 then it could be useful, etc. I don't know what your task is, but so far, the enum is not helping anything really.

note that addr_max is 5, so you can user addr_max to make your array. If you need to grow the array to 10 addresses, only the enum changes and a recompile has the correct array size automatically... this is handy 'future growth' use of an enum.
Last edited on
Ohhh, I see! Yes, I am asking the user to input three addresses, but the array of structs is part of the assignment. I wasn't sure if I needed to define the structs in my array in order to pull that information so that when I ask the user to enter the information for each address, it aligns with the format of the struct. I confused myself royally.
As a starter, consider:

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

constexpr size_t maxAddr {3};

struct Block {
	int streetNumber {};
	std::string street;
	std::string city;
	std::string state;
	int zipcode {};

	//Block() {}
	//Block(int n, std::string& st, std::string& ci, std::string& ate, int zip) : streetNumber(n), street(st), city(ci), state(ate), zipcode(zip) {}

	void input();
};

void Block::input() {
	std::cout << "\nStreet Number: ";
	std::cin >> streetNumber;

	std::cout << "Street: ";
	std::getline(std::cin >> std::ws, street);

	std::cout << "City: ";
	std::getline(std::cin, city);

	std::cout << "State: ";
	std::getline(std::cin, state);

	std::cout << "zipcode: ";
	std::cin >> zipcode;
}

std::ostream& operator<<(std::ostream& os, const Block& bl) {
	return os << bl.streetNumber << ' ' << bl.street << '\n' <<
		bl.city << '\n' << bl.state << '\n' << bl.zipcode << '\n';
}

int main() {
	std::array<Block, maxAddr> address;

	for (auto& a : address)
		a.input();

	for (const auto& a : address)
		std::cout << a << '\n';
}

Here is my new code. The first address works fine, but after the requests for both addresses pops up at the same time and i can't input the information:

#include <iostream>
#include <string>
#include <array>


struct Address
{
int streetNumber{};
std::string street{};
std::string city{};
std::string state{};
int zipcode{};

};


int main()
{
std::array<Address, 5> address{ };
{
std::cout << "Enter your primary address: \n";
std::cin >> address.at(0).streetNumber >> address.at(1).street >> address.at(2).city >> address.at(3).state >> address.at(4).zipcode;


std::cout << "Enter your secondary address: \n";
std::cin>> address.at(0).streetNumber >> address.at(1).street >> address.at(2).city >> address.at(3).state >> address.at(4).zipcode;


std::cout << "Enter an alternative address: \n";
std::cin>> address.at(0).streetNumber >> address.at(1).street >> address.at(2).city >> address.at(3).state >> address.at(4).zipcode;

}

return 0;
}
For primary, you need to use at(0). For secondary you need to use at(1) and for alternative you need to use at(2).

Note that obtaining a string input this way, you can't have a space. Space is considered a separator not as part of the input string. To enable a space to be input as part of a string you use std::getline().

See my post above.
Last edited on
Without checking the validity of the input:
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
#include <iostream>
#include <string>
#include <array>

struct Address
{
   int streetNumber;
   std::string street;
   std::string city;
   std::string state;
   int zipcode;
};

int main()
{
   const unsigned number_houses { 3 };

   // let's create a house block of 3 addresses
   std::array<Address, number_houses> block { };

   // let's ask for the address info for each house on the block
   for (size_t itr { }; itr < number_houses; ++itr)
   {
      std::cout << "House #: ";
      std::cin >> block[itr].streetNumber;

      // mixing stream input methods can cause problems, so we ignore the rest of the
      // buffer when using std::cin followed by std::getline
      std::cin.ignore(32767, '\n'); // ignore up to 32767 characters until a \n is removed

      // a street name could be two or more words, so we use std::getline to retrieve the entire line
      std::cout << "Street Name: ";
      std::getline(std::cin >> std::ws, block[itr].street);

      std::cout << "City: ";
      std::getline(std::cin >> std::ws, block[itr].city);

      std::cout << "State: ";
      std::getline(std::cin >> std::ws, block[itr].state);

      std::cout << "Zipcode: ";
      std::cin >> block[itr].zipcode;
      std::cin.ignore(32767, '\n');

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

   for (size_t itr { }; itr < number_houses; ++itr)
   {
      std::cout << block[itr].streetNumber << ' '
                << block[itr].street << ' '
                << block[itr].city << ", "
                << block[itr].state << ' '
                << block[itr].zipcode << '\n';
   }
}

House #: 123
Street Name: Here Road
City: There
State: On
Zipcode: 789456

House #: 2345
Street Name: Durango
City: Here
State: Off
Zipcode: 456132

House #: 1544
Street Name: My oh my
City: La dee da
State: Denial
Zipcode: 456123

123 Here Road There, On 789456
2345 Durango Here, Off 456132
1544 My oh my La dee da, Denial 456123
@ Furry Guy and seeplus, I see! It looks like I started my array all wrong. I was also focusing on the line for each address instead of the overall number of addresses, which would have defeated the point of the array! I'm driving myself nuts. I'm going to try this again. Thank you!
@Naqq, you were heading in the right direction, just got lost in the weeds for a bit. That happens when first learning any programming language. C++ because of its complexity can make things worse for a bit.

A couple of things to note:

1.
PLEASE learn to use code tags, they make reading and commenting on source code MUCH easier.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either


2. C++ has several different types of containers available. std::array is one, along with a regular array. To create a regular array for the code change line 19 to
18
19
   // let's create a house block of 3 addresses
   Address block[number_houses] { };

The rest of the code needs no change and will still work with the regular array. Both std::array and regular array are compile time constant sized*.

FYI, there is no operator at() with a regular array, just operator [].

If'n you want a run-time variable sized container C++ has std::vector.
https://www.learncpp.com/cpp-tutorial/an-introduction-to-stdvector/

*it is possible to create a run-time sized regular array, but it requires manual memory management. Something you likely haven't been exposed to yet.
@Furry, thanks! I didn't know I could do that. And yes, I was about to scream. I messed up the getlines quite a few times, but I finally got it right.

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


struct address {
	int streetNumber{};
	std::string street{};
	std::string city{};
	std::string state{};
	int zipcode{};

};

int main()
{
	std::array<address, 3>address;

	std::cout << "Address #1\n";

	std::cout << "Street number: ";
	std::cin >> address.at(0).streetNumber;
	std::cout << "Street name: ";
	std::getline(std::cin >> std::ws, address.at(0).street);
	std::cout << "City: ";
	std::getline(std::cin >> std::ws, address.at(0).city);
	std::cout << "State: ";
	std::getline(std::cin >> std::ws, address.at(0).state);
	std::cout << "zipcode: ";
	std::cin >> address.at(0).zipcode;

	std::cout << "Address #2\n";

	std::cout << "Street number: ";
	std::cin >> address.at(1).streetNumber;
	std::cout << "Street name: ";
	std::getline(std::cin >> std::ws, address.at(1).street);
	std::cout << "City: ";
	std::getline(std::cin >> std::ws, address.at(1).city);
	std::cout << "State: ";
	std::getline(std::cin >> std::ws, address.at(1).state);
	std::cout << "zipcode: ";
	std::cin >> address.at(1).zipcode;

	std::cout << "Address #3\n";

	std::cout << "Street number: ";
	std::cin >> address.at(2).streetNumber;
	std::cout << "Street name: ";
	std::getline(std::cin >> std::ws, address.at(2).street);
	std::cout << "City: ";
	std::getline(std::cin >> std::ws, address.at(2).city);
	std::cout << "State: ";
	std::getline(std::cin >> std::ws, address.at(2).state);
	std::cout << "zipcode: ";
	std::cin >> address.at(2).zipcode;

	return (0);
}
Last edited on
If you use a function to obtain the address details, you can simplify the code:

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

struct address {
	int streetNumber {};
	std::string street {};
	std::string city {};
	std::string state {};
	int zipcode {};
};

void getAddress(address& add) {
	std::cout << "Street number: ";
	std::cin >> add.streetNumber;
	std::cout << "Street name: ";
	std::getline(std::cin >> std::ws, add.street);
	std::cout << "City: ";
	std::getline(std::cin, add.city);
	std::cout << "State: ";
	std::getline(std::cin, add.state);
	std::cout << "zipcode: ";
	std::cin >> add.zipcode;
}

int main() {
	constexpr size_t noAdd {3};

	std::array<address, noAdd>address;

	for (size_t a = 0; a < noAdd; ++a) {
		std::cout << "\nAddress #" << a + 1 << '\n';
		getAddress(address[a]);
	}
}

@seeplus. This is so much simpler! Would I be able to do this with vector as well?
Yes, functionally a vector can do everything an array can do (a vector dynamically allocates memory instead).
Perfect. Thanks, Ganado!
The code seeplus posted, rewritten for std::vector (plus some light reformatting):
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
#include <iostream>
#include <vector>
#include <string>

struct address
{
	int         streetNumber {};
	std::string street {};
	std::string city {};
	std::string state {};
	int         zipcode {};
};

void getAddress(address& add)
{
	std::cout << "Street number: ";
	std::cin >> add.streetNumber;

	std::cout << "Street name: ";
	std::getline(std::cin >> std::ws, add.street);

	std::cout << "City: ";
	std::getline(std::cin, add.city);

	std::cout << "State: ";
	std::getline(std::cin, add.state);

	std::cout << "zipcode: ";
	std::cin >> add.zipcode;
}

int main()
{
	constexpr size_t noAdd { 3 };

	std::vector<address> address(noAdd);

	for (size_t a { }; a < noAdd; ++a)
	{
		std::cout << "Address #" << a + 1 << '\n';
		getAddress(address[a]);
		std::cout << '\n';
	}
}

Passing an entire vector into a function doesn't require telegraphing the vector's size, unlike passing a regular array or std::array, the size info is seamlessly passed with the vector.
I definitely took the long way home here! And I can't figure out why my pushback doesn't work. I know I shouldn't have added a class (defeats the purpose of me trying to simplify the code) but I'm not comfortable using it, so I was trying my hand at 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Address {
private:
    string streetNumber;
    string street;
    string city;
    string state;
    string zipcode;

public:
    Address(const string& streetNumber, const string& street, const string& city, const string& state, const string& zipcode) : streetNumber(streetNumber), street(street), city(city), state(state), zipcode(zipcode) {}

    string getStreetNumber() const {
        return streetNumber;
    }

    string getStreet() const {
        return street;
    }

    string getCity() const {
        return city;
    }

    string getState() const {
        return state;
    }

    string getZipcode() const {
        return zipcode;
    }

    void change(string streetNumber, string street, string city, string state, string zipcode) {
        this->streetNumber = streetNumber;
        this->street = street;
        this->city = city;
        this->state = state;
        this->zipcode = zipcode;
    }

    string toString() {
        string result = "Street Number:  " + streetNumber + " Street: " + street + "City: " + city + "State: " + state + "Zipcode: ";
        return result;
    }
};

int main() {
    vector<Address> address;
    string streetNumber, street, city, state, zipcode;
    int n;
    cout << "How many addresses are you entering? ";
    cin >> n;
    getline(cin, streetNumber );
    for (int i = 0; i < n; ++i) {
        cout << "Enter the street number: ";
        getline(cin, streetNumber);
        cout << "Enter the street: ";
        getline(cin, street);
        cout << "Enter the city: ";
        getline(cin, city);
        cout << "Enter the state: ";
        getline(cin, state);
        cout << "Enter the zipcode: ";
        getline(cin, zipcode);
        cout << endl;
        Address p(streetNumber, street, city, state, zipcode);
        Address.push_back(p);
    }
    // display addresses
    for (int i = 0; i < address.size(); ++i) {
        cout << address[i].toString() << endl;
    }
    return 0;
}
Last edited on
With C++ a struct and a class are nearly interchangeable, except for the default access specifier. With a struct the default is public:, with a class it is private:.
L72 Address should be address!

Also you can just do for L71/72 :

 
address.emplace_back(streetNumber, street, city, state, zipcode);

Topic archived. No new replies allowed.