String with character spacing - c++

This program works EXCEPT that it does not allow a space between the first and last name. Below is an example as to what I am talking about:
Link to Picture
Can someone please help me to fix this? I believe it is in string playerName as it will not accept a space between the first and last name.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
// Structure to hold the Player Data
struct Player {
string playerName;
int playerNumber;
int pointsScored;
};
// Function Prototypes
void getPlayerInfo(Player &);
void showInfo(Player[], int);
int getTotalPoints(Player[], int);
void showHighest(Player[], int);
int main(int argc, char *argv[])
{
const int N = 12;
Player players[N];
for (int i = 0; i<N; i++) {
cout << "\nPLAYER #" << i + 1 << "\n";
cout << "---------\n";
getPlayerInfo(players[i]);
}
showInfo(players, N);
int totalPoints = getTotalPoints(players, N);
cout << "TOTAL POINTS: " << totalPoints << "\n";
cout << "The player who scored the most points is :";
showHighest(players, N);
cout << "\n";
system("pause");
return 0;
}
void getPlayerInfo(Player &P) {
cout << "Player Name:";
//cin >> P.playerName; **CHANGED THIS**
cin.ignore(std::numeric_limits<std::streamsize>::max(), ' ');
std::getline(std::cin, P.playerName); **TO THIS**
do {
cout << "Player Number:";
cin >> P.playerNumber;
if (P.playerNumber<0)
cout << "invalid Input\n";
} while (P.playerNumber<0);
do {
cout << "Points Scored:";
cin >> P.pointsScored;
if (P.pointsScored<0)
cout << "invalid Input\n";
} while (P.pointsScored<0);
}
void showInfo(Player P[], int N) {
cout << "\nNAME" << "\t\tNUMBER" << "\t\tPOINTS SCORED" << "\n";
for (int i = 0; i<N; i++)
cout << P[i].playerName << "\t\t" << P[i].playerNumber << "\t\t" << P[i].pointsScored << "\n";
}
int getTotalPoints(Player P[], int N) {
int Points = 0;
for (int i = 0; i<N; i++)
Points += (P[i].pointsScored);
return Points;
}
void showHighest(Player P[], int N) {
int HighestPoint = P[0].pointsScored;
string Name = P[0].playerName;
for (int i = 1; i<N; i++) {
if (HighestPoint<P[i].pointsScored) {
HighestPoint = P[i].pointsScored;
Name = P[i].playerName;
}
}
cout << Name;
}

When std::cin uses operator>> to insert into a std::string, it stops reading at space (' ') characters. Use std::getline instead.
std::getline(std::cin, P.playerName); //read everything up to '\n'

The problem is in this code:
void getPlayerInfo(Player &P) {
cout << "Player Name:";
cin >> P.playerName;//<<----
cin treats ' ' (space) as a delimiter. If you want to have an input with ' ' (space) you need to use: (thanks to #James Root)
//before doing get line make sure input buffer is empty
see also: https://stackoverflow.com/a/10553849/3013996
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin,P.playerName);

Related

Error when passing vectors as parameter in Xcode

I'm working on a program that I've seen other people do online except I'm trying to use functions to complete it to make it somewhat more challenging for me to help me better understand pointers and vectors. The problem I'm having in xcode is I keep getting this error..
Expected ';' after top level declarator
right here on my code,
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers) //<<< Error
{
cout << fixed << setprecision(2);
...
Where I am trying to use vector numbers in my function. Basically I want the numbers from the function passed back so that I can use them in another function I have not created yet. I've googled this error and it seems like no one can give a straight answer on how to fix this problem. Is anyone familiar with how to correct this? By no means is this code finished I'm just trying to get information regarding vectors as a parameter because from what I'm seeing syntax wise on other sites it looks to be correct. Thanks for your feedback.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
struct menuItemType{
string menuItem;
double menuPrice;
};
void getData(menuItemType (&mlist)[8]);
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
int main() {
vector<int> temp;
menuItemType menuList[8];
getData(menuList);
showMenu(menuList,temp);
/*
cout << menuList[0].menuItem << " " << menuList[0].menuPrice << endl;
cout << menuList[1].menuItem << " " << menuList[1].menuPrice << endl;
*/
return 0;
}
void getData(menuItemType (&mlist)[8]){
string Str;
ifstream infile;
infile.open("cafe135.txt");
if(infile.is_open())
{
for (int i = 0; i < 8; ++i){
infile >> mlist[i].menuItem >> mlist[i].menuPrice;
}
}
else cout << "Unable to open file";
}
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
{
cout << fixed << setprecision(2);
string choice;
cout << "Would you like to view the menu? [Y] or [N]: ";
cin >> choice;
cout << endl;
int x = 3;
int count = 1;
while (choice != "Y" && choice != "N" && choice != "y" && choice != "n")
{
if (count == 4){
return;
}
cout << "Error! Please try again ["
<< x
<< "] selections remaining: ";
cin >> choice;
cout << endl;
x--;
count++;
}
if (choice == "N" || choice == "n"){
return;
}
else
{
cout << "___________ Breakfast Menu ___________" << endl;
for (int i = 0; i < sizeof(menu_List)/sizeof(menu_List[0]); ++i)
{
cout << "Item "
<< (i+1)
<< ": "
<< menu_List[i].menuItem
<< " "
<< menu_List[i].menuPrice
<< endl;
}
cout << endl;
string itemSelection = " ";
//int str_length = 0;
cout << "Select your item numbers separated"
<< " by spaces (e.g. 1 3 5) Select 0 to cancel order: ";
cin.ignore();
getline(cin, itemSelection);
if (itemSelection == "0")
{
return;
}
vector<int> vectorItemSelection;
stringstream text_stream(itemSelection);
string item;
while (getline(text_stream, item, ' '))
{
vectorItemSelection.push_back(stoi(item));
}
int n = vectorItemSelection.size();
int arr[n];
for (int i = 0; i < n; i++)
{
arr[i] = vectorItemSelection[i];
}
}
}
Compare how menu_List is declared in this line
void showMenu(menuItemType (&menu_List)[8], vector<int> numbers);
and this line
void showMenu(menuItemType (&menu_List)[8])[], vector<int> numbers)
The first one is correct.
But I have to agree with the comments above, you are mixing up a lot of different things here. Just use vectors, 99% of the time it's the right thing to do anyway. and it's easier to learn one thing at a time.
Prefer to write your code like this
void getData(vector<menuItemType>&);
void showMenu(vector<menuItemType>&, vector<int> numbers);
int main() {
vector<int> temp;
vector<menuItemType> menuList(8);
...
See? Just use vectors everywhere.

How to make output function to write formatted output to both screen and an output file

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
void getInformationKeyBoard(int, string[], int[]);
bool openFile(ifstream &infile, string fileName);
void display(int size, string array[]);
void read2Array(ifstream &infile, int size, string array[]);
void printReport(string name[], int score[], int NumberOfStudent);
int main()
{
const int size = 1024;
string Name[size], scoreFile[size];
int score[size];
int NumberOfStudent;
const int SIZE = 7;
ifstream inFile;
char choice;
cout << "You want to enter your scores by your keyboard (A) or from your input (B): ";
cin >> choice;
if (choice == 'a' || choice == 'A') // It will take information from keyboard
{
cout << "How many students do you want to enter: ";
cin >> NumberOfStudent;
getInformationKeyBoard(NumberOfStudent, Name, score);
printReport(Name, score, NumberOfStudent);
}
else if (choice == 'b' || choice == 'B') // It will take information from file
{
string name;
char again = 'Y';
bool close = false;
cout << "Enter name of file: ";
cin >> name;
openFile(inFile, name);
read2Array(inFile, SIZE, scoreFile);
display(SIZE, scoreFile);
}
else // If you choice is not A,a or B,b
cout << "Your did not follow the right instruction.";
cout << endl << endl;
system("pause");
return 0;
}
// Open file
bool openFile(ifstream &infile, string fileName){
infile.open(fileName);
if (infile)
return true;
return false;
}
void getInformationKeyBoard(int size, string Names[], int scores[]) // Information from keyboard
{
for (int i = 0; i < size; i++)
{
cout << i + 1 << ". Student First Name and Last Name: ";
cin.ignore();
getline(cin, Names[i]);
do
{
cout << i + 1 << ". Enter the score between 1 and 100: ";
cin >> scores[i];
} while (scores[i] > 100 || scores[i] < 0);
}
}
void read2Array(ifstream &infile, int size, string array[]){
int index = 0;
string line;
while (getline(infile, line)){
array[index] = line;
++index;
}
}
// Display array
void display(int size, string array[]){
for (int index = 0; index < size; ++index){
cout << array[index] << endl;
}
}
void printReport(string name[], int score[], int NumberOfStudent)
{
int lowest, highest, mean;
cout << "Enter lowest score: ";
cin >> lowest;
cout << "Enter highest score: ";
cin >> highest;
cout << "Enter mean score: ";
cin >> mean;
cout << "================================================================================";
cout << setw(10) << "Number of scores = " << NumberOfStudent << endl;
cout << setw(10) << "Lowest Score = " << lowest << endl;
cout << setw(10) << "Highest Score = " << highest << endl;
cout << setw(10) << "Mean Score = " << mean << endl;
cout << "Name" << setw(15) << "Score" << setw(15) << "IsLowest" << setw(15) << "IsHighest" << setw(15) << "Mean" << endl;
cout << "-----------------------------------------------------------------" << endl;
cout << name[NumberOfStudent] << endl;
cout << endl;
}
A header statistic section of number of scores, lowest, highest, and mean scores, followed by details for each student - one per line.
I stuck at making output to screen. I want my output look like this
Number of scores = 3
Lowest Score = 82
Highest Score = 92
Mean Score = 87
Name Score IsLowest IsHighest >=Mean
F1 L1 82 Y N N
F2 L2 87 N N Y
F3 L3 92 N Y Y
Perhaps you could pass in a ostream object as a parameter, then replace all occurences of cout in your function with the name of that argument. Then you could run the function twice
printReport(cout, other args);
printReport(outFile, other args);
(Or setup the function to call itself so you don't have to enter cout every time).
The only problem with this method is I see you are grabbing input while inside the function. If you want to use the above method, you'd have to move some things around. Instead, I would setup a different function that takes a string as input and inserts said string to both cout and your file. So rather than having to write
cout<<"hi";
file<<"hi";
You could do
...
functionName("hi", outfile);
...
void functionName(string str, ostream outfile)
{
cout<<str;
outfile<<str;
}
Hope this helps
In general, the following function will work to replicate a console output in a file.
#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
void print(FILE *f, char const *fmt, ...) {
va_list ap;
//Normal console print
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
//Printing to file
if (f != NULL) {
va_start(ap, fmt);
vfprintf(f, fmt, ap);
va_end(ap);
}
}
If you want only console output, simply have
print(NULL, "%d\t%d\n", 1, 100);//include any needed C style formatting here
If you want the console output to be saved to a file, simply pass an appropriate file pointer as the first argument.
FILE *fp = fopen("logfile.txt","a");
print(fp, "%d\t%d\n, 1, 100);//logs the console output to logfile.txt
The console window formatting will be preserved in the text file as well.

Extra string outputs if user input is more than one word

This is my first time asking a question on here, so be gentle lol. I wrote up some code for an assignment designed to take information from a (library.txt datatbase) file, store it in arrays, then access/search those arrays by title/author then output that information for the user based on what the user enters.
The issue I am having is, whenever the user enters in a search term longer than one word, the output of "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: " is repeated several times before closing.
I am just looking to make this worthy of my professor lol. Please help me.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
struct Book
{
string title;
string author;
};
int loadData(string pathname);
char switchoutput();
void showAll(int count);
int showBooksByAuthor(int count, string name);
int showBooksByTitle(int count, string title);
int FindAuthor(int count, string userinput);
int FindTitle(int count, string userinput);
void ConvertStringToLowerCase(const string orig, string& lwr); //I found this program useful to convert any given string to lowercase, regardless of user input
const int ARRAY_SIZE = 1000;
Book books[ARRAY_SIZE];
int main()
{
string pathname;
string name;
string booktitle;
int count = 0;
int counta = 0;
int countt = 0;
char input = 0;
cout << "Welcome to Jacob's Library Database." << endl;
cout << "Please enter the name of the backup file: " ;
cin >> pathname;
count = loadData(pathname);
cout << count << " records found in the database." << endl;
while (toupper(input != 'Q'))
{
input = switchoutput(); // function call for switchoutput function
switch (input)
{
case 'A':
cout << "Author's Name: ";
cin >> name;
counta = showBooksByAuthor(count, name);
cout << counta << " records found." << endl;
break;
case 'T':
cout << "Book Title: ";
cin >> booktitle;
countt = showBooksByTitle(count, booktitle);
cout << countt << " records found." << endl;
break;
case 'S':
showAll(count);
break;
case 'Q':
break;
}
}
//Pause and exit
cout << endl << "Press 'ENTER' to quit";
getchar();
getchar();
return 0;
}
int loadData(string pathname) //loading data into the array of structs
{
ifstream inFile;
inFile.open(pathname);
if (!inFile) {
cout << "Error, could not read into file. Please re-compile." << endl;
system("PAUSE");
exit(1); //if not in file, exit;
}
int i = 0;
while (!inFile.eof()) {
getline(inFile, books[i].title);
getline(inFile, books[i].author);
i++;
}
return i;
}
char switchoutput() //seperate output function to get my characteroutput constantly resetting and returning the uppercase version for my switch
{
char input;
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> input;
return toupper(input);
}
int showBooksByAuthor(int count, string name)
{
int authorcount = 0;
authorcount = FindAuthor(count, name);
return authorcount;
}
int showBooksByTitle(int count, string title)
{
int titlecount = 0;
titlecount = FindTitle(count, title);
return titlecount;
}
void showAll(int count)
{
for (int i = 0; i < count; i++)
{
cout << books[i].title << " (" << books[i].author << ")" << endl;
}
}
int FindAuthor(int count, string userinput)
{
int authorcount = 0;
string stringlower, arraylower;
int num;
// called upon function to lowercase any of the user inputs
ConvertStringToLowerCase(userinput, stringlower);
for (int i = 0; i < count; ++i) //this function's count determines at which locations to output the author and names (an argument from books by author)
{
// called upon function to lowercase any of the stored authors'
ConvertStringToLowerCase(books[i].author, arraylower);
num = arraylower.find(stringlower); // searches string for userinput (in the lowered array) and stores its value
if (num > -1) // you can never get a -1 input value from an array, thus this loop continues until execution
{
cout << books[i].title << " (" << books[i].author << ")" << endl; //cout book title and book author
authorcount++; //count
}
}
return authorcount;
}
int FindTitle(int count, string userinput) //same as previous but for titles
{
int titlecount = 0;
string stringlower, arraylower;
int num;
ConvertStringToLowerCase(userinput, stringlower);
for (int i = 0; i < count; ++i)
{
ConvertStringToLowerCase(books[i].title, arraylower);
num = arraylower.find(stringlower);
if (num > -1)
{
cout << books[i].title << " (" << books[i].author << ")" << endl;
titlecount++; //count
}
}
return titlecount;
}
void ConvertStringToLowerCase(const string orig, string& lwr) // I found this from another classmate during tutoring, I thought to be useful.
{
lwr = orig;
for (int j = 0; j < orig.length(); ++j) //when called upon in my find functions, it takes the string and convers the string into an array of lowercase letters
{
lwr[j] = tolower(orig.at(j));
}
}

printing name in multiple for loops and arrays

I've come across a little problem, how do I print the winning candidate's name? See the instructions here are, input five names, their number of votes and percentage of votes, whoever has the highest wins. I don't know if I did my code right, but it works.. well except for the name part. I've tried everything from a lot of for loops to transfer the array or what.
I'm almost done with the code.
Here's the code
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
char candidates[50];
int votes[5]={0};
float percent[5]={0};
int a,b,c,d,e,i;
int maxx;
int champ=0;
char winner[50];
cout << "Enter the candidates' last names: ";
cout << endl;
for(a=1;a<=5;a++)
{
cout << a << ". ";
cin >> candidates;
}
cout << endl;
cout << "Enter their number of votes: " << endl;
for(b=1;b<=5;b++)
{
cout << b << ". ";
cin >> votes[b];
}
cout << endl;
cout << "percentage of votes: " << endl;
for(c=1;c<=5;c++)
{
cout << c << ". ";
percent[c]=votes[c]*0.2;
printf("%.2f\n", percent[c]);
}
cout <<"Candidates\t\tVotes\t\t% of Votes" << endl;
for(int k=1;k<=5;k++)
{
cout << candidates[k] << "\t\t\t" << votes[k] << "\t\t\t";
printf("%.2f\n", percent[k]);
}
maxx=percent[0];
for(d=1;d<=5;d++)
{
if(maxx<percent[d]);
{
//what happens here?
}
}
return 0;
}
You should keep a 2d array of characters or array of string for storing candidate names instead of a 1-d array.
char candidates[5][10]; //
for(int i = 0; i < 5; i++)
{
cin >> candidates[i];
}
Then keep a variable to store index for winning candidate
int winIndex = 0;
int winPercent = 0;
for(int i = 0; i < 5; i++)
{
if(percent[i] > winPercent)
{
winPercent = percent;
winIndex = i;
}
}
Finally print name of winning candidate;
cout << candidates[winIndex];
In object oriented approach, you may create a class with following information
class Candidate
{
string name;
int votes;
float percent;
};
Use string candidates[50]; instead of char candidates[50];
then cin >> candidates[a];

How to alphabetize a list on C++

I have been having some trouble on my code for my final project. I have looked everwhere and I am having a hard time so I thought I would ask on here. I need to make sure that when all the names are listed in this phonebook that they will come out in alphabetical order but as of yet I am unsure how to do that. Here is the program that i currently have! Thank you!
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
struct Contact {
string name, number, notes;
};
Contact contactList[100];
int rec_num = 0;
int num_entries;
string toUpper (string S) {
for (int i= 0; i < S.length(); i++)
S[i] = toupper(S[i]);
return S;
}
void ReadFile () {
string S;
fstream input("PhoneData.txt");
while (!input.eof() && !input.fail()){
input >> contactList[rec_num].name >> contactList[rec_num].number;
getline(input, S);
contactList[rec_num].notes = S;
rec_num++;
}
cout << "Book read." << endl;
num_entries = rec_num;
input.close();
return;
}
// stores phonebook for future runs of the program
void StoreFile () {
fstream F ("PhoneData.txt");
rec_num = 0;
while (rec_num < num_entries){
F << contactList[rec_num].name << " " << contactList[rec_num].number << " " << contactList[rec_num].notes << " " << endl;
rec_num++;
}
cout << "Phonebook stored." << endl;
return;
}
// adds contact
void add_name(string name, string number, string notes){
contactList[num_entries].name = name;
contactList[num_entries].number = number;
contactList[num_entries].notes = notes;
num_entries++;
return;
}
// finds contact
void retrieve_name(string name){
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
cout << "Phone Number: " << contactList[i].number << endl << "Notes: " << contactList[i].notes << endl;
return;
}
}
cout << "Name not found" << endl;
return;
}
// updates contact info
void update_name(string name){
string new_number;
string new_notes;
cout<<"New Phone Number"<<endl;
cin>> new_number;
cout<<"New Notes"<<endl;
cin>> new_notes;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
contactList[i].number = new_number;
contactList[i].notes = new_notes;
return;
}
}
}
// deletes contact
void delete_name(string name){
int INDEX=0;
for (int i = 0; i < num_entries; i++){
if (toUpper(contactList[i].name) == toUpper(name)) {
INDEX=i;
for ( int j=INDEX; j < num_entries; j++ ){
contactList[j].name = contactList[j+1].name;
contactList[j].number = contactList[j+1].number;
contactList[j].notes = contactList[j+1].notes;
}
}
}
return;
}
void listAllContacts() {
int i = 0;
while (i < num_entries) {
cout << "-- " << contactList[i].name << " " << contactList[i].number << endl << "-- " << contactList[i].notes << endl << endl;
i++;
}
}
int main(){
string name, number, notes;
string FileName;
char command;
FileName = "PhoneData.txt";
ReadFile ();
cout << "Use \"e\" for enter, \"f\" for find, \"l\" for list, \"d\" for delete, \"u\" for update, \"s\" for send message, \"q\" to quit." << endl << "Command: ";
cin >> command;
while (command != 'q'){
switch (command){
case 'e': cin >> name; cout << "Enter Number: ";
cin >> number; cout << "Enter Notes: ";
cin.ignore(); getline(cin, notes);
add_name(name, number, notes); break;
case 'f': cin >> name; retrieve_name(name); break;
case 'l':
listAllContacts(); break;
case 'u': cin>> name; update_name (name);break;
case 'd' : cin>> name; delete_name (name); break;
}
cout << "\nCommand: "; cin >> command;
}
StoreFile();
cout << "All set !";
return 0;
}
Given
Contact contactList[100];
int num_entries;
you can use std::sort to sort the list of contacts. std::sort has two forms. In the first form, you can use:
std::sort(contanctList, contactList+num_entries);
if you define operator< for Contact objects.
In the second form, you can use:
std::sort(contanctList, contactList+num_entries, myCompare);
if you define myCompare to be callable object that can compare two Contact objects.
To use the first form, change Contact to:
struct Contact {
string name, number, notes;
bool operator<(Contact const& rhs) const
{
return (this->name < rhs.name);
}
};
If you want to the comparison of names to be case insensitive, convert both names to either uppercase or lowercase and them compare them.