Filling a struct with a text file

Hi,
Please consider this code. It works well and prints the data correctly.

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
#include <std_lib_facilities_4.h>
using namespace std;

struct Item {
	string name;
	int iid;
	double value;
};

//***************************

int main()
{
	vector<Item> vi;
	ifstream rfile("input.txt");

	if (!rfile) {
		cout << " Failar on opening the file!\n\n";
		system("pause");
		return 1;
	}

	string s;
	int id;
	double value;

	for (size_t i = 0; i < 10; ++i) {
		rfile >> s >> id >> value;
		vi.push_back({ s, id, value });
	}

	for (const auto& v : vi)
		cout << v.name << "  " << v.iid << "  " << v.value << endl;

	cout << "\n";

	system("pause");
	return 0;
}


We have a vector of Items. First we read the data (s, id, value) and then push back them to populate each object of the Item in the vector. The question is, how does the vector put each data (s, id, value) into their corresponding values in the each struct object, because we don't have a constructor for the struct to populate its data (name, iid, value) using a list of arguments.
Last edited on
because we don't have a constructor for the struct to populate its data (name, iid, value) using a list of arguments.

You don’t need 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
#include <iomanip>
#include <iostream>
#include <string>
#include <limits>

struct MyStruct {
    bool one;
    int two;
    double three;
    std::string four;
};

void waitForEnter();

int main()
{
    MyStruct ms { false, 13, 6.66, "goodbye!" };
    std::cout << "Here you are ms: " << std::boolalpha << ms.one << ' '
              << ms.two << ' ' << ms.three << ' ' << ms.four << '\n';
    waitForEnter();
    return 0;
}

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

Here you are ms: false 13 6.66 goodbye!

Press ENTER to continue...


https://docs.microsoft.com/en-us/cpp/cpp/initializing-classes-and-structs-without-constructors-cpp
Thank you.
So, as long as, the values are in order of the declared variables in the struct/class, there is no need to define a constructor for the struct/class.
Be a little bit careful. It's fine for POD structs (and I use it a lot), but for classes in general, think about "encapsulation" and access.

So, as long as, the values are in order of the declared variables in the struct/class, there is no need to define a constructor for the struct/class.


Try adding the access status "private:" to Enoizat's code.

1
2
3
4
5
6
7
struct MyStruct {
private:                  //<===== Add this line
    bool one;
    int two;
    double three;
    std::string four;
};


Alternatively, just change
struct MyStruct {
to
class MyStruct {
since access status is private by default in a class, public in a struct.
Last edited on
I'm not sure what the #include file is, but you only need to #include <vector>, <string>, <fstream>, and <iostream> for this program. The file you're using might have facilities you don't need.
@lastchance, thank you a lot for your clarification, since my answer about structs could indeed be deceitful deceptive. [<-- Edit: corrected]

@Frank14, to my knowledge, as a morsel of consolation :-) , you should always being able to ‘default’ all members, regardless it’s public or not (if they admit a default value, of course):

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

class MyClass {
    bool one;
    int two;
    double three;
    std::string four;
    friend std::ostream& operator<<(std::ostream& os, const MyClass& rhs)
    {
        return os << "Here you are all values: " << std::boolalpha << rhs.one
                  << ' ' << rhs.two << ' ' << rhs.three << ' ' << rhs.four;
    }
};

void waitForEnter();

int main()
{
    MyClass mc1; // random values (at least for primitive types)
    std::cout << "mc1 --> " << mc1 << '\n';
    MyClass mc2 {}; // all defaulted
    std::cout << "mc2 --> " << mc2 << '\n';
    waitForEnter();
    return 0;
}

void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

Output
mc1 --> Here you are all values: true 0 7.69871e-315
mc2 --> Here you are all values: false 0 0

Press ENTER to continue...

Last edited on
Your example (and link) was good, @Enoizat. On the whole it's what I tend to expect when using a struct (where, out of force of habit, I tend to leave everything public).

It was the later (not yours) assumption that it was equally good for classes that was troubling me.
Topic archived. No new replies allowed.