Reputation: 33
Firstly, I'd like to explain what I'm trying to do. So, I have a text file with 10 names followed by their points. I'm trying to create a structure and read information from a file using a function (void). And that's my code and text file:
code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void read(struct laLiga t[]) {
ifstream infile("info.txt");
int i = 0;
while(infile >> t.team[i] >> t.points[i]) {
infile.get(t.team);
infile >> t.points;
i++;
}
}
struct laLiga {
char team[50];
int points;
};
int main() {
struct laLiga t[10];
read(t);
return 0;
}
text file:
Athletic Bilbao 15
Atletico Madrid 18
Barcelona 16
Alaves 10
Las Palmas 12
Real Madrid 18
Real Sociedad 10
Sevilla 17
Eibar 11
Villarreal 16
Upvotes: 1
Views: 1461
Reputation: 2126
if you want to read or write structs in a text file then best would be to use ifstream
read()
function and ofstream
write()
function. Following is how to use them.
#include <iostream>
#include <fstream>
#include <cstring> // for strncpy()
using namespace std;
struct laLiga {
char team[50];
int points;
};
int main()
{
struct laLiga t;
strncpy(t.team,"Some Name",sizeof("Some Name"));
t.points = 100;
//do this for writing a complete struct to a text file at once
ofstream output("info.txt");
output.write(reinterpret_cast<char*>(&t),sizeof(t));
output.close();
//do this for reading a complete struct from a text file at once
struct laLiga T;
ifstream input("info.txt");
input.read(reinterpret_cast<char*>(&T),sizeof(T));
input.close();
//now T will hold both the name and points fields from the text file without doing it individually
cout << "Name = " <<T.team << endl;
cout << "Points = " << T.points << endl;
return 0;
}
OUTPUT (Console)
Name = Some Name
Points = 100
Both read()
and write()
function's first parameter should be char*
that is why we use reinterpret_cast
to cast the complete struct to sequence of bytes and then write to file.
Only drawback of doing like this is that the text file will be unreadable when opened in windows as it wont be normal text but reading and writing would be much easier.
Upvotes: 0
Reputation: 11002
You could use std::vector
to make things easier:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
using namespace std;
auto file_text =
R"(Athletic Bilbao 15
Atletico Madrid 18
Barcelona 16
Alaves 10
Las Palmas 12
Real Madrid 18
Real Sociedad 10
Sevilla 17
Eibar 11
Villarreal 16)";
struct laLiga {
std::string team;
int points;
};
void read(std::vector<laLiga>& t) {
//ifstream infile("info.txt"); // would also work
std::stringstream infile{file_text};
while(infile) {
laLiga laliga{};
std::string partial_team_name{};
while(!(infile >> laliga.points)) { // keep going until we get the points
infile.clear(); // we could not read points, infile stream now in error; clearing to continue
if(infile >> partial_team_name) // maybe the next string is part of a team name
laliga.team += (laliga.team.empty() ? "" : " ") + partial_team_name; // add to team name with space if there was something already in there
else
return; // no points, no team, we're done
}
t.push_back(laliga); // after we get the points we can add the team
}
}
int main() {
std::vector<laLiga> t;
read(t);
for(auto i : t) {
std::cout << std::setw(30) << i.team;
std::cout << std::setw(10) << i.points << '\n';
}
return 0;
}
Output:
Athletic Bilbao 15
Atletico Madrid 18
Barcelona 16
Alaves 10
Las Palmas 12
Real Madrid 18
Real Sociedad 10
Sevilla 17
Eibar 11
Villarreal 16
Upvotes: 2
Reputation: 409166
First of all, you need to define the structure before you use it in the read
function.
Secondly, in the read
function it is the variable t
that is an array, not its members. So you should be using t[i].team
and t[i].points
.
Thirdly, you have already read the data from the file with the >>
operators in the loop condition. You should not read it again inside the loop.
Fourthly, the input file you want to read is actually harder to parse than you think. That is because you can have names both without and with spaces in them. Both the get
function of input streams and the input operator >>
separates on spaces. You should probably read the whole line and then split it at the last space.
Lastly, and actually a reason I should not write an answer is that you haven't actually asked a question, or told us what is wrong with your code. Please read about how to ask good questions for future questions.
Upvotes: 3