It could not work if I type the Name with the space such as Peter Stroll. How to use cin.ignore() in this case?
Thank you in advance.
int main()
{
ofstream File("player.txt");
cout << "Enter player ID, Name, and Money:" << endl;
cout << "Press Ctrl + Z to quit \n" << endl;
int id;
string name;
int age;
while(cin >> id >> name >> age)
{
File << id << " " << name << " " << age << endl;
}
return 0;
}
cin won't accept any more character if it encounters tab or space key.
use getline instead
char name[64] = {0};
cin.getline(name, 64);
Related
using namespace std;
int main()
{
char repeat;
do
{
string str;
cout << "What is your first and last name? " << endl;
getline(cin, str);
string findSpace = " ";
int found = str.find(findSpace) + 1;
cout << str[0] << str[found] << endl;
cout << "repeat? " << endl;
cin >> repeat;
} while (repeat == 'y');
}
I have this code that helps me get the initials of the first and last name. But when I go to repeat the code it automatically couts "What is your first and last name?" as well as "repeat?". It won't go through the steps of asking for the first and last name, giving the initials, and then asking if the user wants to repeat.
What am I doing wrong here?
using namespace std;
int main()
{
char repeat;
do
{
string str;
cout << "What is your first and last name? " << endl;
//
getline(cin >> ws, str);
string findSpace = " ";
int found = str.find(findSpace) + 1;
cout << str[0] << str[found] << endl;
cout << "repeat? " << endl;
cin >> repeat;
} while (repeat == 'y');
}
Thanks to the comment by mch I've solved it. This is my solution.
The code has been updated in order to solve a different section of the whole picture within the coding process. Now I need help within the second case of the switch. The problem now is that the while loop always executes within the second function of the switch. I don't no if the array is verifying the number or the user input.. I could use while (string::npos != studID2[i].find_first_of(studID2[a])) I need some help here it is getting very complex and I am hitting a brick wall.
1)I need to verify each user input using a for loop and two arrays. I tried to increment the of the arrays in order to execute the while statement.
2) If the condition is true the while loop will execute telling the user that he must enter 3 different digits, the reason why I am using an array and a for loop is because the user gets to choose how many names and IDs he would like to input into the archive.
3) The for loop increments a++ in order to check to see if the last input is the same as the newest user input.
It is getting too complex here any help would be appreciated.
Number 4 is the expected error...
4) The second user input will always make the while loop run regardless of what digits you use.
5)The reason for so much code is because I am not completely sure where the problem begins and the problem ends...
6)I am using two arrays here in this problem.
7)There is another error if you change the a from 0 to 1 it will automatically close the program. The reason you would change the a to a 1 is so that a will increment by 1.
//I am trying to verify multiple inputs with a array and a for loop..
// The expected output is that the second ID you input in the second option of the switch case is going to execute the while loop.
//I am trying to execute the while loop properly within the second function of the switch case.
//I need help any form of help can be appreciated.
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include <cstddef>
#include <limits>
#include <cstdlib>
int name2 = 0;
int studentID = 0;
int email2 = 0;
int studentID2[100];
std::string let("abcdefghijklmnopqrstuvwxyz");
int numbers = (1, 3, 0);
std::string str;
std::string name;
std::string studID;
std::string studID2;
std::string email;
std::string emailbackup;
std::string studFinal;
std::stringstream concatenate;
std::stringstream concatenatetwo;
int x;
std::string fileName = "StudentArchive.txt";
void emailEntry();
void readDocument();
int readNumber();
void deleteInformation();
void getStudentinformation();
using std::cout;
using std::cin;
int main()
{
do {
std::cout << "What would you like to do?" << std::endl;
std::cout << "1)Would you like to see the archive?" << std::endl;
std::cout << "2)Would you like to register student information?" << std::endl;
std::cout << "3)Would you like to find a student within the registry?" << std::endl;
std::cout << "4)Delete all student information?" << std::endl;
std::cout << "5)Exit Program?" << std::endl;
std::cin >> x;
switch (x)
{
case 1:
readDocument();
break;
case 2:
emailEntry();
break;
case 3:
deleteInformation();
break;
case 4:
getStudentinformation();
break;
case 5:
cout << "Exiting Program." << std::endl;
system("PAUSE");
break;
}
} while (x != 5);
}
void emailEntry()
{
std::ofstream outfile;
outfile.open(fileName, std::ios_base::app);
int amountofStudent;
std::cout << "How many student Identities would you like to enter?" << std::endl;
std::cin >> amountofStudent;
cin.ignore();
Here is where the user chooses how many students he would like to enter into the registry. I am having difficulty verifying the user input regarding the studentIDs.
if (outfile.is_open()) {
for (int i = 0; i < amountofStudent; i++)
{
std::string studID2[100];
std::stringstream(name) >> name2;
cout << "Please enter your name.." << std::endl;
getline(cin, name);
outfile << name;
std::stringstream(name2) >> name;
while (std::string::npos != name.find_first_of("0123456789"))
{
cout << "You must have letter within user input." << std::endl;
cout << "Please enter your name." << std::endl;
getline(cin, name);
outfile << name;
}
//I need to check to see if the first 3 numbers are correct?
//The student ID must be at least 6 digits, and the first 3 numbers must be 130.
cout << "Please enter Your student I.D." << std::endl;
getline(cin, studID);
outfile << studID;
std::stringstream(studID) >> studentID;
while (/*std::string::npos != studID.find_first_of("130") */ studentID != 130 /*&& studID.length() <= 6*/)
{
std::stringstream(studentID) >> studID;
cout << "You must enter 130 as the first 3 digits" << std::endl;
getline(cin, studID);
std::stringstream(studID) >> studentID;
}
//==============
//std::stringstream(studentID2) >> studID2[i];
cout << "Please enter the second part of the student I.D. " << studentID << "-" << std::endl;
getline(cin, studID2[i]);
outfile << studID;
//outfile << studID2[i];
std::stringstream(studID2[i]) >> studentID2[i];
//cout << i;
This is the for loop, and array I need help with. Below this text is where I am having problems. I don't understand why the while loop won't execute I am trying to verify the first user input with the next user input. For example if the user enters 888 on the first input then tries to enter 888 on the second input they need to re-enter different digits or the input will go on forever. The main struggle is if the user chooses to enter multiple student accounts within this minor registry.
for (int a = 0; a < i; i++)
{
while (studID2[i] == studID2[a])
{
cout << "The numbers cannot be repeated you must re-enter the student ID." << std::endl;
std::stringstream(studentID) >> studID;
cout << "You must enter 130 as the first 3 digits" << std::endl;
getline(cin, studID);
std::stringstream(studID[i]) >> studentID;
//std::stringstream(studID2[i]) >> studentID2;
cout << "Please enter the second part of the student I.D. " << studentID << "-" << std::endl;
getline(cin, studID2[i]);
outfile << studID;
outfile << studID2[i];
//std::stringstream(studID2[i]) >> studentID2;
}
}
This is where the verification of the studentIDs end...
while (/*std::string::npos != studID.find_first_of("130") */ studID2[i].length() < 3 || studID2[i].length() > 3)
{
//stringstream(studentID) >> studID;
cout << "Add 3 more digits." << std::endl;
getline(cin, studID2[i]);
outfile << studID2[i];
}
concatenate << studentID << "-" << studID2 << std::endl;
studFinal = concatenate.str();
/*while (studID.length() != 6)
{
cout << "You must enter 130 as the first 3 digits and you must have 6 digits." << std::endl;
std::cin >> studID;
}*/
cout << "Please enter your email.." << std::endl;
std::stringstream(email) >> email2;
getline(cin, email);
outfile << email;
std::stringstream(email2) >> email;
while (email == emailbackup || email.empty())
{
cout << "Please enter your email..." << std::endl;
std::stringstream(email) >> email2;
getline(cin, email);
outfile << email;
std::stringstream(email2) >> email;
}
concatenatetwo << email << "#atlanticu.edu" << std::endl;
email = concatenatetwo.str();
emailbackup = email;
cout << "Your email is" << email << std::endl;
std::system("pause");
}
}
outfile.close();
}
Here is where the user deletes info..
void deleteInformation()
{
std::ofstream infile(fileName, std::ios::trunc);
if (infile.is_open()) {
cout << "You have now have no books." << std::endl;
system("PAUSE");
system("cls");
infile.close();
}
}
void getStudentinformation()
{
std::ifstream outfile;
outfile.open(fileName);
if(outfile.is_open())
{
int x;
cout << "1)Name" << std::endl;
cout << "2)studentNumber" << std::endl;
cout << "3)Exit" << std::endl;
cin >> x;
switch (x)
{
case 1:
cout << "Please enter the student's name.." << std::endl;
getline(cin, name);
cout << name << std::endl;
outfile >> name;
break;
case 2:
cout << "Please enter the first 3 digits of the student's ID number.. " << std::endl;
getline(cin, studID);
cout << "Please enter the last 3 digits of the student's ID number.. " << std::endl;
getline(cin, studID2);
outfile >> studID;
outfile >> studID2;
break;
case 3:
std::string choice;
cout << "Would you like to return to the main menus?" << std::endl;
cin >> choice;
break;
}
}
}
int readNumber()
{
int number;
cin >> number;
std::string tmp;
while (cin.fail())
{
cin.clear();
std::getline(cin, tmp);
cout << "Only numbers please: ";
cin >> number;
}
getline(cin, tmp);
return number;
}
Here is where the user reads the txt doc.
void readDocument()
{
std::ifstream infile;
infile.open(fileName);
if (infile.is_open()) {
std::string info;
while (getline(infile, info))
{
cout << info << std::endl;
}
infile.close();
}
else {
cout << fileName << " doesn't exists !" << std::endl;
}
std::system("PAUSE");
std::system("cls");
}
//std::ofstream outfile;
//outfile.open(fileName, ios_base::app);
//if(outfile.is_open()) {
// cout << "How many books do you want to add: ";
// int n = readNumber();
// while (n <= 0)
// {
// cout << "Only positive numbers, please: ";
// n = readNumber();
// }
// for (int i = 0; i < n; i++) {
// string title = "Book's Title: ";
// cout << title;
// title += readText();
// string author = "Author: ";
// cout << author;
// author += readText();
// string genre = "Book's Genre: ";
// cout << genre;
// genre += readText();
// cout << endl;
// outfile << title << endl;
// outfile << author << endl;
// outfile << genre << endl << endl;
// }
//}
// outfile.close();
// cout << "Books have been added to the library !" << endl;
// system("PAUSE");
// system("cls");
Think about your function signature.
void email(string emailbackup);
Do you actually want the caller to pass a string to the function email()?
Because you then define emailbackup inside the function again.
You want something like this probably...
...
case 2:
const string backup = "backup#email";
email(backup);
break;
...
void email(string emailbackup)
{
// string emailbackup; // delete this line
...
}
Also, remove using namespace std; and be consistent with your namespace usage. Why add using namespace cout, cin etc if you are calling them with the namespace explicitly i.e. std::cin, std::cout.
Either add using namespace std::cout and use cout rather than std::cout or vice versa. Don't mix it up. Same with std::string and string. Makes it look like you defined your own string...
Just one last thing, for the sake of readability I would suggest breaking this email function into smaller functions. For instance:
void email(string emailbackup)
{
...
int studentID = getStudentID();
string studentEmail = getStudentEmail();
...
}
int getStudentID()
{
int studentID;
cout << "Please enter Your student I.D." << std::endl;
std::cin >> studID;
stringstream(studID) >> studentID;
while (/*std::string::npos != studID.find_first_of("130") */ studentID != 130 /*&& studID.length() <= 6*/)
{
stringstream(studentID) >> studID;
cout << "You must enter 130 as the first 3 digits" << std::endl;
std::cin >> studID;
stringstream(studID) >> studentID;
}
return studentID;
}
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
After my first entry, my second entery name field fills up with the input buffer from the previous entry. Why? I am even using the getline but the problem still persists. Please help me with the problem. This is question from Jumping Into C++ book .
#include <iostream>
#include <string>
using namespace std;
struct Person
{
string name;
string address;
long long int PhoneNumber;
};
void displayEntries(Person p[])
{
int enteryNumber;
cout << "Enter the entry number of the person for details(enter 0 to display all entries): ";
cin >> enteryNumber;
if(enteryNumber == 0)
{
for(int i = 0; i < 10; i++)
{
cout << "Entery Number: " << i + 1;
cout << "Name: " << p[i].name << endl;
cout << "Address: " << p[i].address << endl;
cout << "Phone Number: " << p[i].PhoneNumber << endl;
}
}
do
{
cout << "Entery Number: " << enteryNumber;
cout << "Name: " << p[enteryNumber].name << endl;
cout << "Address: " << p[enteryNumber].address << endl;
cout << "Phone Number: " << p[enteryNumber].PhoneNumber << endl;
} while (enteryNumber != 0);
}
int main()
{
Person p[10];
for(int i = 0; i < 10; i++)
{
cout << "Enter the details of the person\n\n";
cout << "Name: ";
getline(cin, p[i].name);
cout << "Address: ";
getline(cin, p[i].address);
cout << "Phone Number: ";
cin >> p[i].PhoneNumber;
cout << endl;
}
displayEntries(p);
return 0;
}
You can see what is happening when you read the reference for getline:
When used immediately after whitespace-delimited input, e.g. after
int n;
std::cin >> n;
getline(cin, n); //if used here
getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
before switching to line-oriented input.
cin >> p[i].PhoneNumber; only gets the number. That leaves the line ending still in the input buffer to be read the next time you try to read a line.
Why does my code not run properly? As soon as it gets to the if else statement it takes one input from the user and then exits before I can enter anything else. I am not sure if it is due to the function not returning properly but I would really appreciate some help. Thanks.
#include <iostream>
#include <fstream>
using namespace std;
void studentenrollment (char answer);
int main()
{
char answer; //declaring variables for main
cout << "Welcome to Luton Sixth Form" << endl; //greeting the user
cout << "Please State if you are enrolled or not at the sixth form: Y/N" << endl;//giving user options
cin >> answer;//taking options from user
studentenrollment(answer); //calling student enrollment function
return 0;
}
void studentenrollment (char answer)
{
unsigned char name;
int dob;
if (answer=='Y'||answer=='y')
{
cout << "Welcome to higher education" << endl;
cout << "Please state your name" << endl;
cin >> name;
ofstream myfile;
myfile.open("StudentAccess.txt");
myfile << name << endl;
myfile.close();
cout << "Your name is now saved, you have access to the gateway" << endl;
}
else if(answer=='N'||answer=='n')
{
cout << "Please state your name" << endl;
cin >> name;
cout << "Please enter your date of birth" << endl;
cin >> dob;
ofstream myfile;
myfile.open("StudentEnrollment.txt");
myfile << name << dob << endl;
myfile.close();
cout << "You will now go through enrollment" << endl;
}
// return 0;
}
unsigned char name; looks incorrect. Choose char name[MAX_LENGTH]; or std::string name;
What happens
cin >> name; // Read just first character
cin >> dob; // Try to read number, where rest of the name is left in the stream buffer
This certainly looks wrong unless the name is 1 letter wide.
Problem can be this:
cin >> name;
you are entering name but storing it in name - which is just unsigned char. Use a larger array to store the name.
If the variable name can contain more than 1 character you cannot declare it unsigned char, you can declare it std::string. remember the
#include<string>