I have been trying to figure out why it doesn't read my second getline() function. The first getline(cin, input) works fine for getting the input data for partition. I did the same for getting the job datas, and it doesn't work. No errors or anything. it just skips that line. Any help will be greatly appreciated. Thank you.
#include <iostream>
#include <string>
#include "memory.h"
#define show(a) std::cout << #a << ": " << (a) << std::endl
using std::cin;
using std::cout;
using std::endl;
int main(void)
{
//Variables
int MEM_SIZE = 0;
vector<int> partition_input;
vector<int> job_input;
while(true)
{
//INPUT PARTITION DATA
while(true)
{
char confirm;
string input;
int temp; //Temporary variable to store extracted data
int num_part = 0; //Iterator to check partition size and memory, and partition limits
int check_size = 0;
cout << "Please enter the memory size and partitions in the following format: \n";
cout << "1000 250 250 250 250 \n";
cout << "> ";
getline(cin, input); //The whole of user input is stored in variable "line"
istringstream os(input); //"line" is passed to stringstream to be ready to be distributed
while(os >> temp)
{
partition_input.push_back(temp);
check_size += partition_input[num_part];
num_part++;
}
//sets the first input to MEM_SIZE
//AND deletes it from the partition vector
MEM_SIZE = partition_input[0];
partition_input.erase(partition_input.begin(), partition_input.begin()+1);
check_size -= MEM_SIZE;
cout << "Memory size: " << MEM_SIZE << endl;
cout << "# of Partitions: " << partition_input.size() << endl;
cout << "Partition Sizes: ";
for(int i = 0; i < partition_input.size(); i++)
cout << partition_input[i] << ' ';
cout << endl;
cout << "Correct? (y/n) ";
cin >> confirm;
cout << endl << endl;
if(confirm == 'n')
continue;
//Checks the total partition size and the total memory size
if(!(MEM_SIZE >= check_size))
{
cout << "ERROR: Total partition size is less than total memory size." << endl;
system("pause");
continue;
}
//Check if it exceeded the max number of partition limit
if((num_part-1) >=5)
{
cout << "ERROR: You have entered more than the allowed partition(5). Please try again. \n";
system("pause");
continue;
}
break;
}
//START INPUT JOB DATA
do
{
string input2;
cout << "Please enter the size of each job in the following format." << endl;
cout << "300 100 200 400" << endl;
cout << "> ";
//*******************
//IT SKIPS THESE TWO LINES
getline(cin, input2);
istringstream oss(input2);
//*******************
int j;
while(oss >> j)
job_input.push_back(j);
for(int i = 0; i < job_input.size(); i++)
cout << job_input[i] << ' ';
break;
}while(false);
//END OF INPUT JOB DATA
break;
}
Memory A1(MEM_SIZE, partition_input.size(), partition_input, job_input.size(), job_input);
//A1.FirstFit();
// A1.BestFit();
// A1.NextFit();
// A1.WorstFit();
//system("pause");
return 1;
}
The problem is here:
cout << "Correct? (y/n) ";
cin >> confirm;
This reads the confirm character from the input. But not the '\n' character. Thus the next readline will read just that newline character.
It is best not to mix std::getline() and operator>> when reading from the input.
I would change the code to this:
cout << "Correct? (y/n) ";
std::string confirmLine;
std::getline(cin, confirmLine);
cout << endl << endl;
if(confirmLine == "n")
continue;
Related
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;
}
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.
Not under standing looping for arrays. Looping through all of grab some or search. Can someone explain the process? Thanks in advance. Sorry if duplicate. I looked around and couldnt find a solid explaination that I could understand.
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void allContacts(string names[], string phones[])
{
cout << "Showing all contacts... Press Q to go back to main menu" << endl;
}
void addName(string names[], string phones[])
{
bool keepGoing;
string input;
beginning:
for (int i = 0; i < sizeof(names); i++)
{
cout << "Enter contact name: ";
cin >> names[i];
cout << "Enter contact number: ";
cin >> phones[i];
cout << "Do you have another contact to add? y or no" << endl;
cin >> input;
if(input == "y" || input == "Y")
{
goto beginning;
}
if(input == "n" || input == "N")
{
cout << "Contacts you have entered: " << endl;
cout << names[i] << " : " << phones[i] << endl;
}
}
}
void searchName(string names[], string phones[])
{
string name;
cout << "Enter Name: ";
cin >> name;
cout << "Search for a name or Press Q to go back to main menu" << endl;
for (int i = 0; i < sizeof(names); i++){
if (name == names[i])
{
cout << counter << names[i] << " 's phone number is: " << phones[i] << endl;
} else {
cout << "No results found";
}
}
}
int main()
{
string names[100];
string phones[100];
int choice;
cout << "============================" << endl;
cout << "=== Welcome to PhoneBook ===" << endl;
cout << "============================" << endl;
cout << "1- Add a New Contact" << endl;
cout << "2- Search By Name" << endl;
cout << "3- Display All" << endl;
cout << "0- Exit" << endl;
cout << "Select a number: " << endl;
cin >> choice;
switch(choice)
{
case 1:
addName(names, phones);
break;
case 2:
searchName(names, phones);
break;
case 3:
allContacts(names, phones);
break;
case 0:
cout << "Exiting PhoneBook...";
break;
}
}
In C++ arrays lose attributes when passed to functions. Those attributes are capacity and size (number of filled slots). You will need to pass this additional information for each array:
void addName(string names[], unsigned int names_capacity, unsigned int names_size,
string phones[], unsigned int phones_capacity, unsigned int phones_size)
To get around this, you can use std::vector. The std::vector knows its capacity and size, so you don't have to pass additional attributes to your function.
Also, if you use tolower or toupper before you compare, you only need to make one comparison:
char input;
cout << "Do you have another contact to add? y or n" << endl;
cin >> input;
input = toupper(input);
if(input == 'Y')
When using strings, you can convert them to all uppercase or all lowercase by using std::transform, such as:
std::transform(input.begin(),
input.begin(), input.end(),
tolower);
I have to write a program without using strings . Here is my code :
#include <iostream>
#include <iomanip>
using namespace std;
struct product
{
char productName[100];
double productPrice = 0;
};
const int MAX_CHAR = 101;
const int MAX_ITEM = 100;
int main()
{
product item[MAX_ITEM];
double total = 0;
int count = 0;
for (int i = 0; i < MAX_ITEM; i++)
{
cout << "Please , enter the product name(for checkout type -1) : ";
cin.get(item[i].productName, MAX_CHAR, '\n');
cin.ignore(100, '\n');
if (strcmp(item[i].productName, "-1") == 0 ) {
break;
}
else {
count++;
cout << "Please , enter the price for " << item[i].productName << " : $";
cin >> item[i].productPrice;
cin.ignore(100, '\n');
total += item[i].productPrice;
cout << endl << "Product entered : " << item[i].productName << " " << "$"
<< fixed << setprecision(2) <<item[i].productPrice << endl;
cout << "Total : $" << total << endl << endl;
}
}
cout << endl << "###############";
cout << endl << "Your Receipt : " << endl << endl;
for (int i = 0; i < count; i++) {
cout << item[i].productName << " $" << fixed << setprecision(2) << item[i].productPrice << endl;
}
cout << endl << "Total : $" << total;
cout << endl << "###############";
getchar();
getchar();
return 0;
}
I have a couple questions :
Why does the program crash if I don't use cin.ignore(100, '\n'); after cin >> item[i].productPrice; ? It's just cin without any condition, so it should not leave a new line char in input stream?
How can I check if the price doesn't contain incorrect input (so it has only decimal or floating point numbers) ?
How can I check if the name contains chars and numbers which are >0 (except -1) ?
Is it better to use cin.getline in this case ?
cin is an istream, so it should leave the newline char in the stream if you use cin.get(). I haven't tested if this is the cause of your crash but it sounds like this could give you problems.
chars are just numbers. A . is 46, the digit characters are from 48 through 57. You could read your price input into a buffer and check if you read any char that does not have one of your desired values. If you find an unwanted char, you can decide if you want to repeat the input, ignore this item or exit the program.
In your else branch, check if the first character of productName is a '-'. That way, you already ensured that productName is not -1.
cin.getline() discards the newline character, so you could avoid the use of cin.ignore().
I am trying to figure out how to store binary data that is saved to a .dat file "customer.dat" into a structure of vectors. I thought I have had it a few times, but with no luck.
Basically, I have a working method of storing the data into the .dat file, the newEntry function, but I can not seem to work out on how to bring the data back one set at a time into an order structure of vectors. The function in question is the searchDisplay function. Here is the code:
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <string>
#include <cstring>
#include <cctype>
using namespace std;
const int NAME_SIZE = 51, ADDR_SIZE = 51, PHONE_SIZE = 14;
struct Client {
char name[NAME_SIZE];
char address1[ADDR_SIZE];
char address2[ADDR_SIZE];
char phone[PHONE_SIZE];
double acctBal;
double lastPay;
};
//void welcome();
int menu();
int newEntry();
int searchDisplay();
int main() {
int selection;
int option = 0;
int end;
//welcome();
while (option != 6) {
selection = menu();
if (selection == 1) {
cin.ignore();
end = newEntry();
if (end == 0) {
return 0;
}
} else if (selection == 2) {
end = searchDisplay();
if (end == 0) {
return 0;
}
}
}
return 0;
}
int menu() {
int selection;
cout << "User please enter the number that corresponds with what you wish to do..."
<< endl;
cout << "1) Add An Entry" << endl
<< "2) Search for a Specfic Person and erase." << endl;
cin >> selection;
return selection;
}
int newEntry() {
string input;
Client person;
char response = 'y';
//create file object and open file
fstream customer("customer.dat", ios::app | ios::binary);
if (!customer) {
cout << "Error opening file. Program aborting." << endl;
return 0;
}
do {
cout << "Enter person information:" << endl << endl;
cout << "Name: " << endl;
getline(cin, input);
strcpy(person.name, input.c_str());
cout << endl << person.name;
cout << endl << "Street Adress (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin, input);
strcpy(person.address1, input.c_str());
cout << endl << "City, State, Zipcode: " << endl;
cin >> person.address2;
getline(cin, input);
strcpy(person.address2, input.c_str());
cout << endl << "Phone: " << endl;
cin >> person.phone;
getline(cin, input);
strcpy(person.phone, input.c_str());
cout << endl << "Account Balance: " << endl;
cin >> person.acctBal;
//input validation to ensure a non neg number
cin.ignore();
cout << endl << "Last Payment: " << endl;
cin >> person.lastPay;
//input validation to ensure a non neg number
customer.write(reinterpret_cast<char *>(&person), sizeof(person));
cout << endl << "Do you want to enter another record? (Enter Y for Yes, N for No) " << endl;
cin >> response;
cout << "_______________________________________________" << endl << endl;
if (toupper(response) == 'Y') {
cin.ignore();
}
} while (toupper(response) == 'Y');
customer.close();
return 1;
}
/********************************************
My main problem is with the below function
********************************************/
int searchDisplay() {
vector<Client> store(2);
Client foo;
int i = 0;
fstream customer("customer.dat", ios::in | ios::binary);
if (!customer) {
cout << "Error opening file. Program aborting." << endl;
return 0;
}
//MY HOPE WAS THIS WOULD STORE EACH SET OF DATA INTO THE STRUCTURE OF VECTORS
customer.read(reinterpret_cast<char *>(&store), sizeof (store[0]));
while (!customer.eof()){
cout << store[i].name << ":" << endl
<< store[i].address1 << endl
<< store[i].address2 << endl
<< store[i].phone << endl
<< store[i].acctBal << endl
<< store[i].lastPay << endl << endl;
i++;
customer.read(reinterpret_cast<char *>(&store), sizeof (store[i]));
}
customer.close();
return 1;
}
Sorry if any of the coding is a little off in its indenting, I was having issues with the method of putting the code onto the text block.
But yes, any help would be great. This is my first time working with vectors significantly and first time ever with more file classes.
Your first problem is the opening of the data file for writing. You are currently opening it with the flag "ios::app", when it should be "ios::out". Over here (gcc version 4.7.2) i get no output to file when opening the file with "ios::app".
Using "ios::out" it creates a file and dumps the data into it.
The second problem is in the line where you open and read the file. You are missing a "[0]". Check the corrected version below:
customer.read(reinterpret_cast<char *>(&store[0]), sizeof (store[0]));
Making this modifications you can get closer to the desired results.
The main problem here is that writing and reading binary files is a bit different from regular text files, that have indications of line endings, for example. You need to organize your data differently, which can be quite complicated. Try Serializing with Boost.