Why does program complain of too many commas? - c++

Here is my code, I have attached the screenshot of what output Zybooks expects, and what my output is. I am trying to get it to output exactly what Zybooks is asking, however something seams to be wrong. It is compiling though. Or maybe Zybooks is just being stupid?
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <cstring>
using namespace std;
int main() {
string title;
string col1;
string col2;
string val;
int numCommas = 0;
vector<string> stringData;
vector<int> intData;
cout << "Enter a title for the data:" << endl;
getline(cin, title);
cout << "You entered: " << title << endl << endl;
cout << "Enter the column 1 header:" << endl;
getline(cin, col1);
cout << "You entered: " << col1 << endl << endl;
cout << "Enter the column 2 header:" << endl;
getline(cin, col2);
cout << "You entered: " << col2 << endl << endl;
while (1) {
cout << "Enter a data point (-1 to stop input):" << endl;
getline(cin, val);
if (val == "-1") {
break;
}
if (val.find(',') == -1) {
cout << "Error: No comma in string." << endl << endl;
}
else {
for (int i = 0; i < val.length(); i++) {
if (val.at(i) == ',') {
numCommas++;
if (numCommas > 1){
break;
}
}
}
if (numCommas == 1) {
stringData.push_back(val.substr(0, val.find(',')));
intData.push_back(stoi(val.substr(val.find(',') + 1, val.length() - 1)));
cout << "Data string: " << val.substr(0, val.find(',')) << endl;
cout << "Data integer: " << stoi(val.substr(val.find(',') + 1, val.length() - 1)) << endl;
}
else {
cout << "Error: Too many commas in input." << endl << endl;
}
}
}
return 0;
}
Thanks.
Thanks.

Your problem is that you initialise numCommas to zero at the start of the program rather than at the start of each author input. That means, once it exceeds one, it will stay that high at least(a), meaning future inputs will always be seen as having too many commas.
You just need to set it to zero immediately before checking each input.
(a) Well, until it wraps around (if it wraps around). But that will be an awful lot of commas you need to input :-)

Related

Validate string input in c++ for letters and spaces only [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I haven't got to know a lot about functions yet since I'm just at chapter 4 (which is decision making using if, else) of Starting Out with C++ book.
Here my problem asks me to enter the inputs of runner names and their timer so I could rank them in 1st 2nd and 3rd place.
I'm having trouble to validate the input for the string for runners's names as letters and spaces only.
I'm thinking about using loop or bool but I don't know what is the proper way to put it.
Can somebody show me what function I can use best in this case without repeating step into multiple lines of codes.
I'm sorry in advance for my long version code, I'm also looking for the way to shorten it.
#include <iostream>
#include <string>
#include <iomanip> // for setw, setpresicion, control output
#include <cctype> // for getline, cin.
using namespace std;
int main()
{
string runner1, runner2, runner3;
double time1, time2, time3;
cout << "Enter Runner 1 name: ";
getline(cin, runner1);
cout << "Enter Runner 2 name: ";
getline(cin, runner2);
cout << "Enter Runner 3 name: ";
getline(cin, runner3);
cout << runner1 << "'s finishing time: ";
cin >> time1;
while (!cin || (time1 < 0)){ //the # is negative
cout << "Please enter a non-negative number!\n";
cin >> time1;
}
cout << runner2 << "'s finishing time: ";
cin >> time2;
while (!cin || (time2 < 0)){ //the # is negative
cout << "Please enter a non-negative number!\n";
cin >> time2;
}
cout << runner3 << "'s finishing time: ";
cin >> time3;
while (!cin || (time3 < 0)){
cout << "Please enter a non-negative number!\n";
cin >> time3;
}
// This is for Rank1----------------------------
cout << "1st place : ";
if((time1 < time2)&&(time1 < time3))
{
cout << left << setw(5) << runner1 << " " << right
<< setw(5) << time1 << endl;
}
else if (time2 < time3){
cout << left << setw(5) << runner2 << " " << right
<< setw(5) << time2 << endl;
}
else {
cout << left << setw(5) << runner3 << " " << right
<< setw(5) << time3 << endl;
}
//Rank2------------------------------------
cout << "2nd place : ";
if ((time1 < time2)&&(time3 < time1)){
cout << left << setw(5) << runner1 << " " << right
<< setw(5) << time1 << endl;
}
else if ((time3 < time2)&&(time1 < time3)){
cout << left << setw(5) << runner3 << " " << right
<< setw(5) << time3 << endl;
}
else {
cout << left << setw(5) << runner2 << " " << right
<<setw(5) << time2 << endl;
}
// RANK 3-----------------------------------
cout << "3rd place : ";
if ((time1 > time2)&&(time1 > time3)){
cout << left << setw(5) << runner1 << " " << right
<< setw(5) << time1 << endl;
}
else if ((time1 < time3)&&(time3 > time2)){
cout << left << setw(5) << runner3 << " " << right
<< setw(5) << time3 << endl;
}
else {
cout << left << setw(5) << runner2 << " " << right
<<setw(5) << time2 << endl;
}
return 0;
}
This routine will do the validation:
bool validateString(const std::string& s)
{
for (const char c : s) {
if (!isalpha(c) && !isspace(c))
return false;
}
return true;
}
You might want to use something like
#include <cctype>
#include <string>
#include <iostream>
int main()
{
std::string foo;
bool valid;
do {
std::getline(std::cin, foo);
valid = true;
for (std::size_t i{}; i < foo.length() && valid; ++i) {
if (!(std::isalpha(static_cast<unsigned char>(foo[i])) ||
std::isspace(static_cast<unsigned char>(foo[i]))))
valid = false;
}
} while (!valid);
}
which checks every character for being a letter or a space.
Here is my proposal for a solution:
#include <iostream>
#include <string>
bool validateString(std::string toCheck) {
bool correct = false;
for (int i = 0; i<toCheck.length(); i++) {
if ((toCheck[i] >= 65 && toCheck[i] <= 90) || (toCheck[i] >= 97 && toCheck[i] <= 122) || toCheck[i] == 32) {
correct = true;
}
else {
return false;
}
}
return correct;
}
int main()
{
std::cout << validateString("Whats up peeps") << std::endl;
std::cout << validateString("234235") << std::endl;
system("pause");
return 0;
}
Using ASCII Table.
Note: Might not be the best way to do it but it works.

C++ if/else undeclared identifier, trying to use words

I'm trying to make a little game, and I'm a beginner.
The problem is the parts with the ifs and the else, where it says "Lady" and "Sir".
#include <iostream>
#include <string>
using namespace std;
int main()
{
string playerName;
int age;
int playerGender;
cout << "Are you a Lady or a Sir?" << endl;
cin >> playerGender;
if (playerGender = Lady)
{
cout << "So you're a girl. " << endl;
}
else if (playerGender = Sir)
{
cout << "So you're a boy." << endl;
}
cout << "What is your name " << playerGender << "?" << endl;
cin >> playerName;
cout << "What is your age?" << playerName << endl;
cin >> age;
if (age <= 10)
{
cout << "You're too young " << playerName << "! " << endl;
}
else if (age >= 11)
{
cout << "You are old enough to play" << playerName << ". " << endl;
That's what I have, I don't know whats wrong. Help please!
When you perform the following:
std::cin >> playerGender;
You are retrieving a number from the user. You are then assigning that number to your playerGender with the following:
if (playerGender = Lady)
You're only using a single =, which assigns the value that's in Lady to playerGender. You probably mean to write == which will compare the value of playerGender and Lady.
I can't tell what Lady and Sir are, but for your purposes you will need to ensure they are an int:
const int Lady = 0, Sir = 1;
Or an enum:
enum genders { Lady = 0, Sir = 1 };
Now you can make the following comparison:
if (playerGender == Lady)
{
}
else if (playerGender == Sir)
{
}

C++ loop error that my professor can't figure out

I am currently taking a C++ programming class and am working on a project in which I have to create a fairly simple movie database. My code essentially works as intended yet in certain cases it causes the main menu to loop infinitely and I cannot figure out why. I brought this to my teacher and he cannot explain it either. He gave me a workaround but I would like to know if anyone can see the cause of the problem. Full code is as follows:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct MovieType
{
string title;
string director;
int year;
int length;
string rating;
};
MovieType addMovie() {
MovieType newMovie;
cout << "Movie title :";
getline(cin, newMovie.title);
cout << "Director :";
getline(cin, newMovie.director);
cout << "Year :";
cin >> newMovie.year;
cout << "Length(in minutes) :";
cin >> newMovie.length;
cout << "Rating :";
cin >> newMovie.rating;
cout << endl;
return newMovie;
}
void listMovie(MovieType movie) {
cout << "______________________________________" << endl;
cout << "Title : " << movie.title << endl;
cout << "Director : " << movie.director << endl;
cout << "Released : " << movie.year << endl;
cout << "MPAA Rating : " << movie.rating << endl;
cout << "Running time : " << movie.length << " minutes" << endl;
cout << "______________________________________" << endl;
}
void search(vector<MovieType> movieVector) {
string strSearch;
cout << endl << "Search title: ";
getline(cin, strSearch);
for (int c = 0; c < movieVector.size(); c++) {
if (movieVector.at(c).title == strSearch)
listMovie(movieVector.at(c));
}
}
int main() {
bool quit = 0;
vector<MovieType> movieVector;
while (quit == 0) {
char selection = 'f';
cout << "Main Menu:" << endl;
cout << "'a' - Add movie" << endl;
cout << "'l' - List movies" << endl;
cout << "'s' - Search by movie title" << endl;
cout << "'q' - Quit" << endl;
cout << "Please enter one of the listed commands:";
cin >> selection;
cin.ignore();
cout << endl;
if (selection == 'a')
movieVector.push_back(addMovie());
else if (selection == 'l') {
for (int c = 0; c < movieVector.size(); c++) {
listMovie(movieVector.at(c));
}
}
else if (selection == 's') {
search(movieVector);
}
else if (selection == 'q')
quit = 1;
}
return 0;
}
When an unexpected input type is entered during the addMovie function(like entering text for the int type year), it just runs through the function then loops through the menu infinitely. It appears to me that the code just stops even looking at the input stream. I have tried using cin.ignore() in many different places but it doesn't matter if there is nothing left in the stream it just keeps going.
I am using NetBeans to compile my code.
I really have no idea why it behaves like this otherwise I would offer more information but I am just curious as to why this happens, because as I said before, my professor doesn't even know why this is happening.
Any help or insight is greatly appreciated.
cin enters an error state where cin.fail() is true. In this state it just ignores all input operations. One fix is to clear the error state, but better, only use getline operations on cin, not formatted input.
E.g., instead of
cin >> newMovie.year;
… do
newMovie.year = stoi( line_from( cin ) );
… where line_from can be defined as
auto line_from( std::istream& stream )
-> std::string
{
std::string result;
if( not getline( stream, result ) )
{
// Throw an exception or call exit(EXIT_FAILURE).0
}
return result;
}
Disclaimer: code untouched by compiler.

I am trying to use a do while loop to repeat a certain portion of my program and it refuses to execute properly

Okay so as the title said its refusing to execute the stuff right under the "do" function even though as far as i can tell all the parameters for a repeat have been fulfilled. So far what i get when i run the program is something along the lines of...
"Would you like to search another name?
Please enter Y for yes and n for no:"
looping over and over when i press y
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main()
{
vector <string> vName, vID, vClass;
string sName, sID, sClass, sSearch, cQuestion;
int iSize, iStudent;
// Display initial vector size
iSize = vName.size();
cout << "Student list starts with the size:" << iSize << endl;
// Get size of list from user
cout << "How many students would you like to add?" << endl;
cin >> iStudent;
cin.ignore();
// Get names, ids, and classes
for (int i = 0; i < iStudent; i++)
{
cout << "Student" << i + 1 << ":\n";
cout << "Please enter the student name: ";
getline(cin, sName);
vName.push_back(sName);
cout << "Enter ID number ";
getline(cin, sID);
vID.push_back(sID);
cout << "Enter class name ";
getline(cin, sClass);
vClass.push_back(sClass);
}
// Display header
cout << "The list of students has the size of: " << iStudent << endl;
cout << "The Student List" << endl;
cout << "\n";
cout << "Name:" << setw(30) << "ID:" << setw(38) << "Enrolled Class : " << endl;
cout << "--------------------------------------------------------------------------";
cout << "\n";
// for loop for displying list
for (int x = 0; x < vName.size() && vID.size() && vClass.size(); x++)
{
cout << vName[x] << "\t \t \t" << vID[x] << "\t \t \t" << vClass[x] << endl;
}
// Sorting function
cout << "\n";
cout << "The Student List after Sorting:" << endl;
cout << "\n";
sort(vName.begin(), vName.end());
for (int y = 0; y < vName.size(); y++)
{
cout << vName[y] << endl;
}
cout << "\n";
// Search function
do
{
cout << "Please Enter a name to be searched:" << endl;
getline(cin, sSearch);
if (binary_search(vName.begin(), vName.end(), sSearch))
{
cout << sSearch << " was found." << endl << endl;
}
else
{
cout << sSearch << " was not found." << endl << endl;
}
cout << "Would you like to search another name?" << endl << endl;
cout << "Please enter Y for Yes and N for No:" << endl << endl;
cin >> cQuestion;
} while (cQuestion == "Y" || cQuestion == "y");
cout << "Thank you for using this program!" << endl;
return 0;
}
Edit:
Posted whole program, please excuse any grammatical mistakes, I'm just trying to get the program down before i go in there and make it pretty.
The tail of your loop does this:
cout << "Please enter Y for Yes and N for No:" << endl << endl;
cin >> cQuestion;
which will consume your string if you entered one, but leave the trailing newline in the input stream. Thus when you return to the top of the loop after entering Y or y, and do this:
cout << "Please Enter a name to be searched:" << endl;
getline(cin, sSearch);
the getline will extract an empty line.
How to consume the unread newline from the input stream is up to you. You will likely just end up using .ignore() as you did prior in your program. Or use getline to consume cQuestion. You have options. Pick one that works.
And as a side note, I would strongly advise you check your stream operations for success before assuming they "just worked". That is a hard, but necessary, habit to break. Something like this:
do
{
cout << "Please Enter a name to be searched:" << endl;
if (!getline(cin, sSearch))
break;
if (binary_search(vName.begin(), vName.end(), sSearch))
{
cout << sSearch << " was found." << endl << endl;
}
else
{
cout << sSearch << " was not found." << endl << endl;
}
cout << "Would you like to search another name?" << endl << endl;
cout << "Please enter Y for Yes and N for No:" << endl << endl;
} while (getline(cin,cQuestion) && (cQuestion == "Y" || cQuestion == "y"));
If cQuestion is a char array then you need to use strcmp or stricmp to compare it with another string i.e. "Y" and "y" in this case. If cQuestion is a single char then you need to compare with 'Y' and 'y' (i.e. with a single quote)
Strings in C++ are not first class types therefore they do not have some of the string operation that exist for other basic types like ints and floats. You do have std::string as part of the standard C++ library which almost fulfills the void.
If you just change the type of cQuestion to std::string your code should work but if you want to stick with chars then you will need to change the quote style.

C++ If Else statement Problems

My code contains an If Else statement. I want it to validate a string that a user inputs puts into the script on two things:
The length of the string has to be more than 0
The string has to consist of alphabet characters
Below is my code, I think the error is to do with the length of the string piece of code.
Before Edit:
cout << "Your word: " << szOriginal << "\n";
if szOriginal.length() > 0 and (isalpha(szOriginal))
{
szWord = szOriginal.tolower();
cout << szWord << "\n";
}
else
{
cout << "Please enter a valid word." << endl;
}
Sorry guys, the error produced by Dev-C++ is
expected '(' before "szOriginal"
Link to printscreen: http://gyazo.com/b3f43928072e9c2a5a8a712a9030364d
After Edit with variable declaration and such:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
int main(int nNumberofArgs, char* pszArgs[])
{
string original;
cout << "Welcome to the English to Pig Latin translator!\n";
cout << "Type a word you wish to translate:\n";
cin >> original;
cout << "Your word: " << original << "\n";
if (original.length() > 0 && (isalpha(original)) )
{
word = original.tolower();
cout << Word << "\n";
}
else
{
cout << "Please enter a valid word." << endl;
}
system("PAUSE");
return 0;
}
So sorry for this bad post!
if ( [...] ) - you're missing the brackets.
Also, it's && instead of and.
I think you are coming from a python background
cout << "Your word: " << szOriginal << "\n";
if (szOriginal.length() > 0 && (isalpha(szOriginal)) )
{
szWord = szOriginal.tolower();
cout << szWord << "\n";
}
else
{
cout << "Please enter a valid word." << endl;
}
you need ( ) around the if condition, and use && for logical and
EDIT
you are using szOriginal as a char when you say isalpha(szOriginal)
and as an object when you say szWord = szOriginal.tolower();
so you need to look into that also