C++: output with extra zero in struct - c++

I am the beginner of C++, just start to learn struct.
I create the struct and read the data from a file.
Here is my file:
John Smith 26832904 1657 Commerce st Flushing NY 11204 7183942833 company01 962 51
I successfully input the data to the struct. The output is perfect but just having a zero at the end, which can drive me crazy.
This is my entire code:
#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
using namespace std;
struct nametype
{
string first;
string last;
};
struct addresstype
{
string address1;
string address2;
string address3;
string city;
string state;
string zip;
};
struct contacttype
{
string home;
string person;
};
struct employeeType
{
nametype name;
string id;
addresstype address;
contacttype contact;
string worklocate;
double basewage;
int carsale;
};
int main()
{
ifstream infile;
infile.open("employeeInfor.txt");
if (!infile)
{
cout << "Error." << "\n";
}
employeeType employee;
employee.basewage = 0.0;
employee.carsale = 0;
infile >> employee.name.first >> employee.name.last
>> employee.id
>> employee.address.address1 >> employee.address.address2
>> employee.address.address3 >> employee.address.city
>> employee.address.state >> employee.address.zip
>> employee.contact.home >> employee.contact.person
>> employee.worklocate
>> employee.basewage >> employee.carsale;
cout << employee.name.first <<" "<<employee.name.last
<< " " << employee.id
<< " " << employee.address.address1 << " " << employee.address.address2
<< " " << employee.address.address3 << " " << employee.address.city
<< " " << employee.address.state << " " << employee.address.zip
<< " " << employee.contact.home << " " << employee.contact.person
<< " " << employee.worklocate
<< " " << employee.basewage << " " << employee.carsale << "\n";
infile.close();
system("pause");
return 0;
}
I output the data. That's what I got:
The end of the extra 0 is not my expectation.
By the way. I want to put the struct within the array. To make this function work for more than one employee. I know should be create the struct like, employeeType employees[5];
I just stuck from reading the file. Can't keep moving.

You try to read 14 values, but your input file contains only 13. So the last value you output, employee.carsale is 0 as in the initialization.

You read 14 parameters but your file only provides 13. Maybe you forgot to add a column in employeeInfor.txt.

Related

Can I put a string, int, and double in a vector?

In my program, I'm having an issue with one function trying to put three different types into an array. Is that possible, or do I have to work around this? I need them in one vector so I can recall that array in another function to delete it.
void addStudent()
{
string major;
double gpa;
unsigned seed = time(0);
srand(seed);
int rand_ID = rand() % 9000 + 1000;
cout << "Please enter major" << endl;
cin >> major;
cout << "Please enter GPA" << endl;
cin >> gpa;
cout << "------Add Student------" << endl;
cout << "ID: " << rand_ID << endl;
cout << "Major: " << major << endl;
cout << "GPA: " << gpa << endl;
ofstream students;
students.open("students.txt", ios_base::app);
students << rand_ID << " " << major << " " << gpa << endl; // I want to turn this into an array that I can send to the file students
}
It sounds like you want to put different students in a vector; and those students will be represented by a struct containing an int ID, string major and double GPA.
struct Student {
int id;
std::string major;
double gpa;
};
std::vector<Student> students;

Using += operator on a string in order to add .txt for file output

I'm currently taking the first CompSci class in college and one of my assignments wants me to take a name as input, then use that name in order to make a file with that same name, but with ".txt" at the end.
It prints out what it should be named as, but I can't find any file under the name I tried inputting.
Does anyone know what went wrong?
#include<iostream>
#include<fstream>
#include<iomanip>
#include<math.h>
using namespace std;
int main()
{
string des_name;
string ship_name;
float ship_mass;
float e_thrust;
const float g0 = 9.8;
cout << "Designer name: " << endl;
getline(cin , des_name);
cout << "Ship Name: " << endl;
cin >> ship_name;
ship_name += ".txt";
cout << "Ship Mass: " << endl;
cin >> ship_mass;
cout << "Engine Thrust: " << endl;
cin >> e_thrust;
cout << "File written for " << ship_name;
ofstream output_file;
output_file.open(des_name.c_str());
output_file << "##########" << ship_name << "##########" << endl << endl;
output_file << "Designed by: " << setw(10) << des_name;
}
Hmm, you open a file based on des_name, yet it's ship_name that you appended .txt to:
ship_name += ".txt";
:
output_file.open(des_name.c_str());
I'd be looking at that anomaly as a starting point :-)

How do I add vectors into my structs to create an inventory system in which I can add multiple different wines to the system using only one struct?

I have a school assignment in which I have to create a Wine Inventory System where the user can add multiple different wines without a finite number I assume.
I need to create vectors but I'm not sure. I don't know what to try.
#include <string>
#include <iostream>
#include <vector>
using namespace std;
struct Wine1
{ //struct for Wine pssibly needs Vector
string name;
string year;
string place;
string price;
} wine;
void printwine(Wine1 wine);
int main()
{
string str; //input for data
cout << "Please enter the data of the First wine: " << endl;
cout << "Enter name: ";
getline(cin, wine.name);
cout << endl << "Enter year: ";
getline(cin, wine.year);
cout << endl << "enter country of creation: ";
getline(cin, wine.place);
cout << endl << "enter price: ";
getline(cin, wine.price);
cout << endl;
cout << "your entered data: " << endl;
printwine(wine);
cout << endl;
printwine2(wine2);
cout << endl;
printwine3(wine3);
}
void printwine(Wine1 wine)
{ //data the user typed as output
cout << "Wine1" << endl;
cout << "the name is: " << wine.name << endl;
cout << "it's year is: " << wine.year << endl;;
cout << "its country of creation is: " << wine.place << endl;;
cout << "it's price is: " << wine.price << endl;
}
It should output the name of the wine, the year, it's country, and it's price, for each wine which was added.
A good starting should be using vector of Wine1.
std::vector<Wine1> wineVec;
wineVec.reserve(/*size*/) // reserve the memory if you know the number of wines beforehand
The printwine function should now take std::vector<Wine1>(preferably const-reference as the data is read-only) and iterate through the vector to print the attributes of the Wine1.
Something like:
#include <string>
#include <iostream>
#include <vector>
void printwine(const std::vector<Wine1>& vecWine)
{
for (const auto& wine : vecWine)
{
// do printing each: wine.name, wine.year,... so on
}
}
int main()
{
std::vector<Wine1> vecWine;
int wineNumber = 2;
vecWine.reserve(wineNumber);
std::string name, year, place, price;
for (int i = 0; i < wineNumber; ++i)
{
// get the user input for name, year, place, and price
std::cin >> name >> year >> place >> price;
vecWine.emplace_back(Wine1{ name, year, place, price });
}
printwine(vecWine);
}
That said, you should read more about std::vector
to get to know more, how it works.
Also, good to read about, how to overload operator>> and operator<<, so that you could even write code, much simpler.
Following is an incomplete code, which I leave you to complete after covering the topics which I mentioned.
void printwine(const std::vector<Wine1>& vecWine)
{
for (const auto& wine : vecWine)
{
std::cout << wine << '\n';
}
}
int main()
{
std::vector<Wine1> vecWine(wineNumber);
for (Wine1& wine : vecWine)
{
std::cin >> wine;
}
printwine(vecWine);
}
I believe there is a misunderstanding: you do not intend your struct Wine1 to contain a vector but instead, you want a vector of Wine1's.
I suggest a data structure similar to the following:
struct Wine {
string name;
string year;
string place;
string price;
};
void printwinelist(vector<Wine>& list){
for(Wine& w : list){
printwine(w);
}
}
vector<Wine> winelist;
The main method has to be rewritten accordingly, to append additional objects to the vector.
While I could rewrite your code accordingly I suspect, that a better next step for you would be to read up on some of the concepts used, such as vectors.
You probably want something like this:
#include <string>
#include <iostream>
#include <vector>
using namespace std;
struct Wine1
{ //struct for Wine pssibly needs Vector
string name;
string year;
string place;
string price;
};
void printwine(Wine1 wine);
int main()
{
vector<Wine1> wineinventory;
// read 3 wines
for (int i = 3; i < 10; i++)
{
Wine1 wine;
string str; //input for data
cout << "Please enter the data of the First wine: " << endl;
cout << "Enter name: ";
getline(cin, wine.name);
cout << endl << "Enter year: ";
getline(cin, wine.year);
cout << endl << "enter country of creation: ";
getline(cin, wine.place);
cout << endl << "enter price: ";
getline(cin, wine.price);
cout << endl;
cout << "your entered data: " << endl;
printwine(wine);
wineinventory.push_back(wine); // store in vectore
}
// print all wines in the vector
for (int i = 0; i < wineinventory.size(); i++)
{
cout << "Wine " << i << ":" endl;
printwine(wineinventory[i]);
}
}
Disclaimer: this is untested code, I'm not even sure if it compiles, but you should get the idea.
There is still much room for improvement.

How to create a function to read/write data to struct members?

I'm trying to create a program that read and print students' data with c++. for that, I've created a struct Student, a function to read data from the user and assign it to a struct instance s1 and a function to print students' data on the screen, and I think the problem is with the function that read/write data.
Here is the my code:
#include<iostream>
#include<string>
using namespace std;
struct Student
{
char name[30];
int age;
double gpa;
string department;
};
Student read_data(Student x)
{
cout << "Name (30 characters maximum): ";
cin.get(x.name, 30);
cout << "Age: ";
cin >> x.age;
cout << "Department: ";
cin >> x.department;
cout << "GPA: ";
cin >> x.gpa;
return x;
}
void print_data(Student x)
{
cout <<
"\n***************************************************************" << endl;
cout << "Name: " << x.name << endl;
cout << "Age: " << x.age << endl;
cout << "Department: " << x.department << endl;
cout << "GPA: " << x.gpa << endl;
}
int main()
{
Student s1, s2, s3;
cout << "This program stores -Temporarily- data of three students\n" << endl;
cout << "Enter 1st student's data" << endl;
read_data(s1);
print_data(read_data(s1));
system("pause");
return 0;
}
The output of this code is:
This program stores data of three students
Enter 1st student's data
Name (30 characters maximum): Ahmed Maysara
Age: 22
Department: CS
GPA: 3.5
Name (30 characters maximum): Age: Department: GPA:
***************************************************************
Name:
Age: -858993460
Department:
GPA: -9.25596e+61
Press any key to continue . . .
As you see, the output is out of my expectations :) ..
Any help ?!
Both CinCout and David are correct.
There are a couple of problems with your code as it now stands.
The first problem is that while you successfully call the function read_data(s1), s1 is a just a copy. So, when the function sets all of the values for the student using cin, it is really just setting a copy's values. You can either make it so that you are passing in the original, or you can return the student (which you are doing) and set s1 equal to the result (which you are not).
To make sure that you pass in the original, you can go to where you declared read_data. Instead of saying Student read_data(Student x), you should place an ampersand after the parameter that you don't want to copy Student read_data(Student &x). This is called passing by reference (you reference the original instead of referencing by copy)
Alternatively, you could con just set s1 to the result where you call it in main. You could say s1 = read_data(s1); and that would work fine, though a bit more inefficiently.
Lastly, the other glaring error in the code is that you accidentally call read_data again when you say print_data(read_data(s1)). Instead, say print_data(s1).
Instead of passing and returning the structure object each time on call of read_data and print_data we could add those inside the structure itself, We could create object of Student and call the functions read and print within the same.
struct Student
{
char name[30];
int age;
double gpa;
string department;
Student(): age(0), gpa(0)
{
memset( name, 0, 30 );
}
void read()
{
cout << "\nName (30 characters maximum): ";
cin.get(name, 30);
cout << "\nAge: ";
cin >> age;
cout << "\nDepartment: ";
cin >> department;
cout << "\nGPA: ";
cin >> gpa;
}
void print()
{
cout << "\n***************************************************************" << endl;
cout << "Name: " << name << endl;
cout << "Age: " << age << endl;
cout << "Department: " << department << endl;
cout << "GPA: " << gpa << endl;
}
};
int main()
{
Student s1;
s1.read();
s1.print();
return 0;
}
You are passing copy of s1 into the read_data function, but not bothering to update the value based on the return arg. i.e. something like this should work.
s1 = read_data(s1);
print_data(s1);
Alternatively, pass by reference instead of value:
void read_data(Student& x)
{
cout << "Name (29 characters maximum): "; // requires null terminator
cin >> x.name; // just read into the buffer directly
cout << "Age: ";
cin >> x.age;
cout << "Department: ";
cin >> x.department;
cout << "GPA: ";
cin >> x.gpa;
}
And then later:
read_data(s1);
print_data(s1);
change you read_data with something like this
void read_data(Student& x)
{
cout << "Name (30 characters maximum): ";
///cin.get(x.name, 30);
cin.getline(x.name, 30);
cout << "Age: ";
cin >> x.age;
cin.ignore();
cout << "Department: ";
std::getline(cin, x.department);
///cin >> x.department;
cout << "GPA: ";
cin >> x.gpa;
cin.ignore();
// return x; can't return a value from a void function
}
and in main function or where you are calling the read_data function use
Student s1, s2, s3;
cout << "This program stores -Temporarily- data of three students\n" << endl;
cout << "Enter 1st student's data" << endl;
read_data(s1);
read_data(s2);
read_data(s3);
the reason you are getting weird values in return is that you capture buffer with cin >> instead getline
see
description of getline function
description of cin.ignore function

Why won't Xcode (10.1) realize this class? What am I doing wrong

Basically trying to just run this program for extra learning, Xcode won't understand that I have written a class, and wont implement it. Really confused and need some guidance.
When I run the code only the main method is implemented, nothing else works...
#include <iostream>
using namespace std;
class students {
int id;
char name[20];
int s1;
int s2;
int s3;
public:
void getData() {
cout << "Enter the ID " << endl;
cin >> id;
cout << "Enter the name " << endl;
cin >> name;
cout << "Enter the grade in subject 1 " << endl;
cin >> s1;
cout << "Enter the grade in subject 2 " << endl;
cin >> s2;
cout << "Enter the grade in subject 3 " << endl;
cin >> s3;
}
void putData() {
cout << id << " " << name << " " << s1 << " " << s2 << " " << s3 << endl;
}
};
int main () {
students s[20];
int i, n; //i is for the for loop, n for number of students
cout << "Enter the number of students " << endl;
cin >> n;
for (i=0;i>n;i++)
{
s[i].getData();
}
for (i=0;i>n;i++)
{
s[i].putData();
}
return 0;
}