Why my code is not executing and showing me error ?? Im getting error on this line
while (getline(s, word, ' , '))
my Code is below:
#include <fstream>
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
// first we define a class that will represent all the candidates
class Candidate
{
string name;
int votes;
public:
Candidate()
{
name = "";
int votes = 0;
}
Candidate(string cand_name, int vote_count)
{
name = cand_name; votes = vote_count;
} string getName() { return name; } int getVotes() { return votes; } void get_details() { cout << name << ", " << votes << endl; }
//Following member method is used to increment the vote count
void vote_this_candidate() { votes++; }
};
int main()
{
cout << "Welcome to Student President Voting System!!!" << endl;
Candidate allCandidates[100];
int totalVotes = 0;
// File pointer fstream fin; // Open an existing file
fstream fin;
fin.open("candidantes.txt", ios::in); // Read the Data from the file // as String Vector
vector <string> row;
string line, word, temp; int index = 0; // Following while loop will iterate for each line in the file
while (fin >> temp) {
row.clear(); // read an entire row and // store it in a string variable 'line'
getline(fin, line); // used for breaking words
string s(line); // read every column data of a row and // store it in a string variable, 'word'
while (getline(s, word, ' , '))
{ // adding the splitted words to row
row.push_back(word);
} allCandidates[index] = Candidate(row[0], stoi(row[1])); totalVotes += stoi(row[1]); index++;
}
string name = ""; cout << "\nPlease enter the name of the candidante you want to vote : ";
getline(cin, name); int cand_no = -1; string userChoice; int i = 0; //Now we find the candidante with the same inputted name
while (i < index) {
if (allCandidates[i].getName() == " " + name) {
cand_no = i; cout << "Do you want to vote this candidante [y/n] : ";
cin >> userChoice; //After finding the candidate just ask the user to vote the candidante
if (userChoice == "y") { //to vote just call the member method that increments the vote count
allCandidates[cand_no].vote_this_candidate(); totalVotes++; cout << endl << "You successfully voted to " << name << " Thanks for voting!!!" << endl;
}
else { cout << "You didn't vote!!!" << endl; } break;
}
i++;
} if (cand_no == -1) {
cout << "Candidante not found!!! Do you like to add this candidate [y/n]: ";
cin >> userChoice; if (userChoice == "y") { allCandidates[index + 1] = Candidate(name, 1); totalVotes++; index++; }
}
//To show top five candidates we first sort the array with lambda
std::sort(allCandidates, allCandidates + 10, [](Candidate a, Candidate b) -> bool { return a.getVotes() > b.getVotes(); });
//then we show only first five candidates
cout << endl << "These are top 5 candidantes so far : " << endl;
for (int i = 0; i < 5; i++)
{
cout << i + 1 << ","; allCandidates[i].get_details();
} cout << endl << "Total studnets voted: " << totalVotes;
}
Problem is here:
string s(line);
while (getline(s, word, ' , '))
because getline has no overload that takes a std::string as its first parameter.
However, there is an overload that takes a stringstream, so you can do:
stringstream ss(line);
while (getline(ss, word, ' , '))
Also, ' , ' won't do what you think. Perhaps you meant ','.
Finally, int votes = 0; in your Candidate() constructor should just be votes = 0;. As it is, you are just declaring, initialising and then discarding a local variable.
The problem is that the compiler is telling you that the parameters you've given don't match a definition of the function. In your case I believe the problem is that you've given it 3 characters instead of 1 in the character portion (remember, a space is also a character). Try changing ' , ' to ','
Related
I have a program that takes input for names and outputs the last names in a string. The task I have now is to include FileIO in it. Specifically, "get user input for the filename, and then read the names from the file and form the last name string."
When I run the program, the console will show the name string from the text file. But only initially. As you keep entering names, that string disappears. Also, my user input for file name seems to be doing nothing, because I can enter anything and it still show the string of last names from the text file.
Here is what I have so far. Included all of it, just to make sure.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
using namespace std;
// function declerations
int Menu();
void getName(vector<string> &names, int &count);
void displayName(vector<string> &names, int count);
string getLastNames(vector<string> &names, int count);
int main()
{
vector<string> names;
int count = 0;
int choice = Menu();
ifstream File;
string line;
cout << "Enter file name: ";
getline(cin,line);
File.open("File.txt");
while(File.good()){
getline(File,line);
cout << line << endl;
}
File.close();
while (choice != 0)
{
// switch statement to call functions based on users input
switch (choice)
{
case 1: {
getName(names, count);
} break;
case 2: { displayName(names, count); } break;
case 3: {
cout << getLastNames(names, count) << endl;
} break;
case 0: {
return 0;
} break;
}
choice = Menu();
}
return 0;
}
// function definition for vector of strings
void getName(vector<string> &names, int &count)
{
string name;
// get input for name
cout << "Enter name: ";
getline(cin, name);
// find position of space in string
int pos = name.find(' ');
// reverse order of name
if(pos != -1) {
string first = name.substr(0, pos);
string last = name.substr(pos+1);
name = last + "," + first;
}
// add name to end of vector
names.push_back(name);
count++;
}
// give user option of what to do
int Menu() {
int choice;
cout << "1. Add a name" << endl;
cout << "2. Display names " << endl;
cout << "3. Show all Last Names" << endl;
cout << "0. Quit" << endl;
cout << "Enter a option: ";
cin >> choice;
// if outside of above choices, print 'choice not on list'
while (choice < 0 || choice > 3)
{
cout << "Choice not on list: ";
cin >> choice;
}
cin.ignore();
return choice;
}
// defining function that gets last names
string getLastNames(vector<string> &names, int count) {
stringstream ss;
for (int i = 0; i<count; i++)
{
int pos = names[i].find(',');
if (pos != -1) {
ss << "\"" << names[i].substr(0, pos) << "\", ";
} else {
ss << "\"" << names[i] << "\", ";
}
}
return ss.str();
}
// display the names
void displayName(vector<string> &names, int count)
{
if (count == 0)
{
cout << "No names to display" << endl;
return;
}
for (int i = 0; i<count; i++)
{
cout << names[i] << endl;
}
}
I've been working on a program to display user input in a table and a histogram, I've got those down, but I can't figure out how to take the user input and separate it by a comma and save the first part as a string and the second as an integer. I used streams but it separates it by spaces and the string might need to have spaces in it, so that's not reliable. I also tried substrings but I need the second half to be an int. Any tips are appreciated. Thank you.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <ctype.h>
using namespace std;
int main() {
string title, col1, col2, userInput, one, two;
istringstream inSS;
string lineString;
string author;
int books;
vector<string> vecAuthors;
vector<int> vecBooks;
bool inputDone;
cout<<"Enter a title for the data:"<<endl;
getline(cin, title);
cout<<"You entered: "<<title<<endl;
cout<<"Enter the column 1 header:"<<endl;
getline(cin, col1);
cout<<"You entered: "<<col1<<endl;
cout<<"Enter the column 2 header:"<<endl;
getline(cin, col2);
cout<<"You entered: "<<col2<<endl;
while (!inputDone) {
cout<<"Enter a data point (-1 to stop input):"<<endl;
getline(cin, lineString);
while (lineString.find(',') == string::npos) {
if (lineString == "-1") {
break;
}
cout << "Error: No comma in string.\n" << endl;
cout << "Enter a data point (-1 to stop input):" << endl;
getline(cin, lineString);
}
string::size_type position = lineString.find (',');
if (position != string::npos)
{
while (lineString.find (',', position+1) != string::npos) {
if (lineString == "-1") {
break;
}
cout << "Error: Too many commas in input." << endl;
cout << "Enter a data point (-1 to stop input):" << endl;
getline(cin, lineString);
}
}
one = lineString.substr(0, lineString.find(','));
two = lineString.substr(lineString.find(',') + 1, lineString.size() - 1);
inSS.clear();
inSS.str(lineString);
inSS >> author;
inSS >> books;
if (inSS.fail()) {
if (lineString == "-1") {
break;
}
cerr << "Error: Comma not followed by an integer." << endl << endl;
cout << "Enter a data point (-1 to stop input):" << endl;
getline(cin, lineString);
}
inSS.clear();
inSS.str(lineString);
inSS >> author;
if (author == "-1") {
cout<<"Finished."<<endl;
inputDone = true;
}
else {
inSS >> books;
author.pop_back();
vecAuthors.push_back(author);
vecBooks.push_back(books);
cout << "Data string: " << author << endl;
cout << "Data integer: " << books << endl;
}
}
cout<<setw(33)<<right<<title<<endl;
cout<<setw(20)<<left<<col1<<"|";
cout<<setw(23)<<right<<col2<<endl;
cout<<setfill('-')<<setw(43)<<""<<endl;
cout<<setfill(' ');
for(int i=0; i<vecAuthors.size(); ++i){
cout<<setw(20)<<left<<vecAuthors[i]<<"|"<<setw(23)<<right<<vecBooks[i]<<endl;
}
cout<<endl;
for(int i=0; i<vecAuthors.size(); ++i){
cout<<setw(20)<<right<<vecAuthors[i];
for(int k = 0; k<vecBooks[i]; ++k) {
cout<<left<<"*";
}
cout<<endl;
}
return 0;
}
Code to get the first part to a string and second part to an int:
#include <iostream>
#include <string>
int main()
{
std::string input{};
std::cin >> input;
int commaSlot{};
for (int i = 0; i < input.length(); i++) {
if (input[i] == ',') {
commaSlot = i;
break;
}
}
std::string firstPart = input.substr(0,commaSlot);
int secondPart = std::stoi(input.substr(commaSlot+1));
std::cout << firstPart << " " << secondPart;
}
because what you need is quite custom (you need comma as a separator and not space ) you can get a line and parse it as you want with the getline function of std afterwards you can separate the string on the comma (the simplest way I can think off is a simple for loop but you can use std's algorithm's also) and then you can use the stoi function to convert a string to an int ,all of them together:
std::string row{};
unsigned positionofcomma{};
std::getline(std::cin,row);
for (unsigned i=0;i<row.length();i++)
if (row[i]==','){
positionofcomma=i;
break;
}
std::string numberstring=row.substr(positionofcomma+1, row.length());
int number=std::stoi(numberstring);
c++ Microsoft visual studio on a windows.
im very new to coding. currently going through Programming -- Principles and Practice Using C++ by Stroupstrup and I came across a difficulty. I am to create a "score chart" with vector name and vector score from the user input. I used for-loop to get the input. now I am to modify the program so that with 2nd input from the user I can search the list and "cout<<" the score for a person. the problem is the the program completely ignores the 2nd "cin>>" command.
I search online and could not find a reasonable answer to this problem. Is there any special interaction between a for-loop input being terminated and another input (not looped)
syntax:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> name;
vector<int> score;
string temp2;
int i;
for (string temp; cin >> temp >> i;) //input terminated with "Ctrl+Z"
name.push_back(temp), score.push_back(i);
for (int i = 0; i < name.size(); ++i) {
for (int j = i + 1; j < name.size(); ++j) {
if (name[i] == name[j]) {
name[j] = "error";
score[j] = 0;
}
}
}
for (int i = 0; i < name.size(); ++i) {
cout << name[i] << "------" << score[i] << "\n";
}
cout << "name"; //this line shows in the console
cin >> temp2; //but I cannot prompt the user to input again?
return 0;
}
CTRL-Z is interpreted as "End-Of-File", such that any subsequent access to this stream will not read in items any more. The only secure way is to change program logic such that the list of names is terminated by, let's say "END", and not a CTRL-Z. Then you can continue in a save manner.
Often input from a terminal is read in line by line and parsed afterwards. This makes error handling easier. See the following code following such an approach:
#include <sstream>
int main() {
string line;
map<string,int> scoreboard;
cout << "enter name score (type END to finish):" << endl;
while (std::getline(cin, line) && line != "END") {
stringstream ss(line);
string name;
int score;
if (ss >> name >> score) {
scoreboard[name] = score;
} else {
cout << "invalid input. Type END to finish" << endl;
}
}
cout << "enter name:" << endl;
string name;
if (cin >> name) {
auto item = scoreboard.find(name);
if (item != scoreboard.end()){
cout << "score of " << name << ":" << item->second << endl;
}
else {
cout << "no entry for " << name << "." << endl;
}
}
}
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));
}
}
My Text File:
Name G M S
Cart 1 0 1
Jane 0 1 0
What I have so far:
#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <algorithm>
using namespace std;
void scoreChanger();
string line;
int main()
{
string yn;
int ctr = 0;
ifstream infile;
infile.open("WiiTourney.txt");
if (infile.is_open())
{
cout << "This is your current score table: " << endl;
while(getline(infile, line))
{
ctr++;
cout << line << endl;
cout << ctr << endl;
}
cout << endl;
}
else
{
cout << "Unable to open file" << endl;
}
infile.close();
cout << endl;
cout << "Would you like to change the scores? " << endl;
cin >> yn;
transform(yn.begin(), yn.end(), yn.begin(), ::tolower);
if (yn == "yes")
{
scoreChanger();
}
else
{
infile.close();
return 0;
}
return 0;
}
void scoreChanger()
{
string name;
ofstream outfile;
outfile.open("WiiTourney.txt");
if (outfile.is_open())
{
cout << "Who won the game? " << endl;
cin >> name;
transform(name.begin(), name.end(), name.begin(), ::tolower);
if (name == "jane")
{
while(getline(outfile, line))
{
cout << line << endl;
}
}
for (int x = 0; x < line.length(); x++)
{
if (line[x] == 8 && line[x] != 'G')
{
}
}
}
else
{
cout << "Error opening file. " << endl;
exit(1);
}
}
What I want it to do:
Let's say I wanted to be able to add 1 point to the Games column(G) only for Cart. The problem for me is that I only want to change the 1 in the G column and I know that I would encounter problems by just looping through and searching for instances where 1 comes up because there could be multiple 1's in one line. I am also getting the error on the line while(getline(outfile, line)) that says "no matching function for call to 'getline(std::ofstream&, std::string&)'"
Thank you, your help is very much appreciated.
My first thought was that the structure of the table is very uniform, so you could determine the position of a specific score using columns and rows.
Because the names are the only elements with variable length (assuming the scores don't go above 9, because that would give 2 characters), I would first read the first word of every row and input this into an array of names.
From this you can find specific elements using the row and column indices. If C++ doesn't contain a function to get characters based on row and column indices, I would loop through the file and add each character to the corresponding position in a 2-dimensional array.
For example:
characters[0][0]
would return N, from the start of "Names".
And of course to retrieve the score you incorporate the length of the name the specific line to get the value:
characters[names[0].length()+1][1]
This would return the score under G for the first name in the list.