Can somebody please explain to me why this code won't execute the while condition?
I just want to know why the code behaves this way or if there are other ways to make it work.Thanks
UPDATE!!!
Hi by the way this is the code, I am not very familiar with C++ so I am not sure while the program skips the while condition on switch. Thanks
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define MAX 100
using namespace std;
int main()
{
void remove(char[]);
void add(char[], char);
char cstring[MAX];
char letter;
int ecount;
std::string str;
char selection;
cout << "Enter String: ";
cin.getline(cstring, MAX);
cout << "Size of String: " << strlen(cstring) << endl;
bool gameOn = true;
while (gameOn != false){
cout<<"\n Menu";
cout<<"\n========";
cout<<"\n A - Append";
cout<<"\n X - Exit";
cout<<"\n Enter selection: ";
cin>>selection;
switch(selection)
{
case 'A' :
case 'a' :
cout << " Add Element: ";
while (letter!='\n')
{
letter = cin.get();
add(cstring, letter);
}
cout << "\n Output String: " << cstring;
ecount = strlen(cstring) - 1;
cout << " Size of String: " << ecount<< endl;
break;
case 'X' :
case 'x' :{cout<<"\n To exit the menu";}
break;
default : cout<<"\n !!Invalid selection!!"<< endl;
}
}
cout<<"\n";
return 0;
}
char * add( char *cstring, char c )
{
int letter = strlen( cstring );
if ( letter < MAX - 1 )
{
cstring[letter] = c;
cstring[letter + 1] = '\0';
}
return ( cstring );
}
Its my wild guess.
I think you have to initialize letter.
check it out by using the following code.
And yes debug for the value of selection you are passing to switch too.
switch(selection)
{
case 'A' :
case 'a' :
cout << "Add Element: ";
letter = cin.get(); // this will initialize the char letter;
while (letter != '\n') // or use ascii value of new line char in while condition
{
add(cstring, letter); // first add it to string
letter = cin.get(); // then get next letter
}
cout << "String: " << cstring;
ecount = strlen(cstring) - 1; // ecount must be a int
cout << "Size of String: " << ecount<< endl;
break;
Hope this will help you
The problem is in the input you are reading, When you read a character in the
cin>>selection;
It will read a char and put it into selection and when you press enter it will be get stored in the letter and you'r while loop will never execute.
see the code below it is working fine;
#include<iostream>
#include <stdio.h>
#include <string.h>
#include<algorithm>
#include<cstring>
#include<vector>
#define MAX 100
using namespace std;
int main()
{
void remove(char[]);
void add(char[], char);
char cstring[MAX];
char letter;
int ecount;
std::string str;
char selection;
cout << "Enter String: ";
cin.getline(cstring, MAX);
cout << "Size of String: " << strlen(cstring) << endl;
bool gameOn = true;
while (gameOn != false){
cout<<"\n Menu";
cout<<"\n========";
cout<<"\n A - Append";
cout<<"\n X - Exit";
cout<<"\n Enter selection: ";
cin>>selection;
cout<<"\n selection="<<selection;
switch(selection)
{
case 'A' :
case 'a' :
selection=cin.get();
cout << " Add Element: ";
while (letter!='\n')
{
letter = cin.get();
add(cstring, letter);
}
cout << "\n Output String: " << cstring;
ecount = strlen(cstring) - 1;
cout << " Size of String: " << ecount<< endl;
break;
case 'X' :
case 'x' :cout<<"\n To exit the menu";
gameOn=false;
break;
default : cout<<"\n !!Invalid selection!!"<< endl;
}
}
cout<<"\n";
return 0;
}
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;
}
}
This is a program that grade user inputs for the questions of Driver's License Exam.
I'm having trouble of validating the user input.
I'd like to accept the [ENTER] key as an invalid input and proceed to my validation rather than just go to an empty line and cannot process to the next question. Purpose is to send out error message and that no input is given and [ENTER] key is not valid input and only accept one more chance to enter valid input which are a/A, b/B, c/C, or d/D. So that is why I'm using if statement here instead of loop.
I tried if (testTakerAnswers[ans] == (or =) '\n') {} but still doesn't solve the problem of newline.
I include curses.h in here hope to use getch() statement from the other post but somehow I can't manage to work in my code with an array instead of regular input.
I'm looking for other methods as well rather than getch()
So should I adjust my bool function, or directly validate input in main() function.
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <curses.h>
using namespace std;
const unsigned SIZE = 20; // Number of qns in the test
char testTakerAnswers[SIZE]; //Array to hold test taker's answers
bool validateInput(char);
class TestGrader
{
private:
char answers[SIZE]; // Holds the correct answers // Answer is array
int getNumWrong (char[]);
void missedQuestions (char[]);
public:
void setKey(string); // Initialize object with standard keys
void grade(char[]); // Grades the answers from tester
};
void TestGrader::setKey(string key){
if (key.length()!=SIZE){
cout << "Error in key data.\n";
return;
}
for (unsigned pos = 0; pos < SIZE ; pos ++)
answers [pos] = key [pos];
}
void TestGrader::grade(char test[])
{
int numWrong = getNumWrong(test);
if (numWrong <= 5)
cout << "Congratulations. You passed the exam.\n";
else
cout << "You did not pass the exam. \n";
cout << "You got " << (SIZE-numWrong) << " questions correct. \n";
if (numWrong > 0){
cout << "You missed the following " << numWrong << " questions: \n";
missedQuestions(test);
}
}
int TestGrader::getNumWrong(char test[])
{
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
counter++;
}
}
return counter;
}
void TestGrader::missedQuestions(char test[])
{
// cout << testTakerAnswers[i]; This is to print taker's answers
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
cout << "\n" << i + 1 << ". Correct answers: " << answers[i];
counter++;
}
}
}
bool validateInput(char ans){ // Only A, B, C, D valid input
if (toupper(ans)!='A' && toupper(ans)!= 'B' && toupper(ans)!='C' && toupper(ans)!= 'D'){
cout << "\n********************WARNING*******************\n";
cout << "Invalid input! Enter only a/A, b/B, c/C, or d/D\n";
return false;
}
if (testTakerAnswers[ans] == '\n'){
return false;
}
return true;
}
int main()
{
const int NUM_QUESTIONS = 20;
string name; //Test taker's name
char doAnother; //Control variable for main processing loop
TestGrader DMVexam; //Create a TestGrader object
DMVexam.setKey("BDAACABACDBCDADCCBDA");
do {
cout << "Applicant Name: ";
getline(cin,name);
cout << "Enter answer for " << name << ".\n";
cout << "Use only letters a/A, b/B, c/C, and d/D. \n\n";
for (int i = 0; i < NUM_QUESTIONS; i++){
// Input and validate it
do{
cout << "Q" << i+1 << ": ";
cin >> testTakerAnswers[i];
if (!validateInput(testTakerAnswers[i])){
cout << "You get one more chance to correct.\nOtherwise, it count as wrong answer.";
cout << "\n*********************************************";
cout << "\nRe-enter: ";
cin >> testTakerAnswers[i];
cout << '\n';
break;
}
}while(!validateInput(testTakerAnswers[i]));
}
//Call class function to grade the exam
cout << "Results for " << name << '\n';
DMVexam.grade(testTakerAnswers);
cout << "\nGrade another exam (Y/N)? ";
cin >> doAnother;
while (doAnother != 'Y' && doAnother != 'N' && doAnother != 'y' && doAnother != 'n'){
cout << doAnother << " is not a valid option. Try Again y/Y or n/N" << endl;
cin >> doAnother;}
cout << endl;
cin.ignore();
}while(doAnother != 'N' && doAnother != 'n');
return 0;
}
Your issue is cin >> testTakerAnswers[i]; cin is whitespace delimited, that means that any whitespace (including '\n') will be discarded. So testTakerAnswers[i] can never be '\n'.
I'm not sure exactly what you want to do, but possibly try
getline(cin,input_string);
then
input_string == "A" | input_string == "B" | ...
So if only the enter key is pressed, input_string will become "".
Novice C++ user trying to practice program building. The point of this program is just simple name storage with vectors.
My previous program https://pastebin.com/MG1hHzgK works perfectly fine for just adding first names.
This upgraded version is supposed to have an input of First Last names then it is converted into Last, First name before being added to the list.
My problem is that after I input names, they arent added to the list. The differences between my previous program and current one are all in the function addNames and to me it looks correct when its obviously not.
Any hints or help is greatly appreciated.
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Prototypes
string addNames(vector <string>& nameList);
string removeName(vector <string>& nameList);
int findName (vector <string>& nameList);
void showList(vector <string>& nameList);
void commandList(vector <string>& nameList);
void inputCall(vector <string>& nameList);
void sortList(vector <string>& nameList);
int main()
{
vector <string> nameList;
commandList(nameList);
}
void commandList(vector <string>& nameList)
{
cout << "\nPress any key to continue..." << endl;
getch();
system("cls");
cout << "Enter a Command " << endl;
cout << "<A> - Add names to the list" << endl;
cout << "<R> - Remove a name from the list" << endl;
cout << "<F> - Search for a name on the list" << endl;
cout << "<L> - Show current state of the list" << endl;
cout << "<S> - Sort the list" << endl;
cout << "<Q> - Ends the program" << endl;
inputCall(nameList);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
string addNames(vector <string>& nameList)
{
string input;
int pos = input.find(' ');
nameList.clear();
for (;true;)
{
cout << endl;
cout << "Enter a Name or 'Stop' to end name entry: " << endl;
getline(cin, input);
if (input == "Stop" || input == "stop"){
commandList(nameList);
} else if(pos != -1) {
string first = input.substr(0, pos);
string last = input.substr(pos + 1);
input = last + "," + first;
nameList.push_back(input);
commandList(nameList);
}
}
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
string removeName(vector <string>& nameList)
{
string x;
cout << endl;
cout << "Enter the name to remove: " << endl;
cin >> x;
for (int i=0; i < nameList.size(); ++i) {
if (nameList[i]== x) nameList[i]="";
}
commandList(nameList);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
int findName (vector <string>& nameList)
{
string target;
int i, x=0;
int p=0;
cout << endl;
cout << "Enter a name to search for: " << endl;
cin >> target;
if (target == "Quit" || target == "quit") {exit(0);
}
for (int i=0; i < nameList.size(); i++)
{
if (nameList[i] == target)
{
cout << endl;
cout << "The entered name is listed as #" << p+1 << '.' << endl;
commandList(nameList);
return p;
}
if (nameList[i] == "") {
p--;
}
p++;
}
cout << endl;
cout << "Name not found!" << endl;
commandList(nameList);
return -1;
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void showList(vector <string>& nameList)
{
cout << endl;
cout << "The current state of the list is: " <<endl;
for (int i=0; i<nameList.size(); i++)
if(nameList[i] !="")
cout << nameList[i] << endl;
commandList(nameList);
}
void sortList(vector <string>& nameList)
{
string temp;
for (int i=0; i < nameList.size()-1; i++)
{
for (int j=0; j < (nameList.size()-i-1); j++)
{
if (nameList[j] > nameList[j+1])
{
temp = nameList[j];
nameList[j] = nameList[j+1];
nameList[j+1] = temp;
}
}
}
cout << endl;
cout << "The list has been sorted alphabetically." << endl;
commandList(nameList);
}
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
void inputCall(vector <string>& nameList) // Function to complement the menu for switch casing
{
bool running = true;
char input;
do {
input = getch();
switch(input)
{
case 'a': addNames(nameList);break;
case 'A': addNames(nameList);break;
case 's': sortList(nameList);break;
case 'S': sortList(nameList);break;
case 'l': showList(nameList);break;
case 'L': showList(nameList);break;
case 'f': findName(nameList);break;
case 'F': findName(nameList);break;
case 'r': removeName(nameList);break;
case 'R': removeName(nameList);break;
case 'q': exit(0);break;
case 'Q': exit(0);break;
default : cout << "Unknown Command: Enter a command from the menu." << endl; continue;
}
} while (running);
}
if you insert
pos = input.find(' '); in else { } just above ( if(pos != -1) )
Your code will work
I am new to c++ and and am working on a program that has is a simple dvd rental program. I am having issues with case 3 & 4 specifically. Maybe I am misunderstanding the purpose behind sizeof. What I am trying to have it do is tell if the char array is empty and if it is allow the user to check it out by putting their name in and if it is not available give them a response saying that it is not available. case 4 should do the opposite and allow them to check it in. Any suggestions would be greatly appreciated.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <limits>
using namespace std;
const int arrSize = 5;
struct dvdStruct //distance struct
{
int id;
char title[51] = { 0 };
char rating[5] = { 0 };
double price;
char borrower[51] = { 0 };
} dvd;
dvdStruct dvds[arrSize] = {};
int userSelection; //intput variable for main menu selection
int borrowId (0);
int borrowIdReturn(0);
//void initalize();
int main() {
int size(0);
dvds[0].id = 1;
dvds[1].id = 2;
dvds[2].id = 3;
dvds[3].id = 4;
dvds[4].id = 5;
strcpy(dvds[0].title, "Fast 1");
strcpy(dvds[1].title, "Fast 2");
strcpy(dvds[2].title, "Fast 3");
strcpy(dvds[3].title, "Fast 4");
strcpy(dvds[4].title, "Fast 5");
strcpy(dvds[0].rating, "PG - 13");
strcpy(dvds[1].rating, "PG - 13");
strcpy(dvds[2].rating, "PG - 13");
strcpy(dvds[3].rating, "PG - 13");
strcpy(dvds[4].rating, "PG - 13");
dvds[0].price = '19.1';
dvds[1].price = '19.2';
dvds[2].price = '19.3';
dvds[3].price = '19.4';
dvds[4].price = '19.5';
strcpy(dvds[0].borrower, "");
cout << strlen(dvds[0].borrower) << endl;
strcpy(dvds[1].borrower, "\0");
strcpy(dvds[2].borrower, "\0");
strcpy(dvds[3].borrower, "\0");
strcpy(dvds[4].borrower, "\0");
do {
cout << "1.Display All DVD’s" << endl << "2.Display DVD Detail" << endl << "3.Check Out a DVD" << endl << "4.Check In a DVD" << endl << "5.Exit" << endl;
cin >> userSelection; //Input from the user.
switch (userSelection)
{
case 1:
for (int i = 0; i < arrSize; i++)
{
std::cout << dvds[i].title << "' " << dvds[i].rating << " " << dvds[i].borrower << endl;
}
system("pause");
system("CLS");
break;
case 2:
int dvdNum;
cout << "Enter a DVD number:";
cin >> dvdNum;
std::cout << dvds[dvdNum - 1].title << "' " << dvds[dvdNum - 1].rating << endl;
system("pause");
system("CLS");
break;
case 3:
cout << "Enter and id:";
cin >> borrowId;
if (strlen(dvds[borrowId-1].borrower) == 0)
{
cout << "Enter your name: ";
cin >> dvds[borrowId-1].borrower;
}
else
{
cout << "This dvd is not available" << endl;
}
system("pause");
system("CLS");
break;
case 4:
cout << "Enter and id:";
cin >> borrowIdReturn;
if (strlen(dvds[borrowIdReturn - 1].borrower) == 0)
{
cout << "This dvd is available" << endl;
}
else
{
cout << "Your DVD has been returned " << endl;
strcpy(dvds[borrowIdReturn - 1].borrower, "\0");
}
system("pause");
system("CLS");
break;
case 5:
return 0;
break;
}
} while (userSelection == 1 || userSelection == 2 || userSelection == 3 || userSelection == 4);
}
sizeof() gives you the size of an object. The size of the object is always the same, no matter what's in the object. In fact, sizeof() is calculated at compile time, and its value could not be affected, in any way, by whatever happens at runtime.
C++ code should use std::string, instead of char arrays, in most cases. std::string's empty() method indicates whether the string is empty.
If you still insist on working with C-style char arrays, and C-style '\0' terminated strings, use the C strlen() function to check if the character array contains nothing but a leading '\0', indicating an empty string.
First off, thanks in advance for your help. This issue is driving me nuts.
I have a program that accepts a c-string, and then can count the number of vowels and consonants. This works without issue. However, I also need to include a function that allows the user to create a new string. The problem is, though, when the user selects "new string" from the menu, it just loops through the newString() method, without waiting for the user's input. It then creates a new, blank screen.
Here is the entire program. The newString() method is at the end.
#include <iostream>
using namespace std;
// function prototype
void printmenu(void);
int vowelCount(char *);
int consCount(char *);
int cons_and_vowelCount(char *);
void newString(char *, const int);
int main() {
const int LENGTH = 101;
char input_string[LENGTH]; //user defined string
char choice; //user menu choice
bool not_done = true; //loop control flag
// create the input_string object
cout << "Enter a string of no more than " << LENGTH-1 << " characters:\n";
cin.getline(input_string, LENGTH);
do {
printmenu();
cin >> choice;
switch(choice)
{
case 'a':
case 'A':
vowelCount(input_string);
break;
case 'b':
case 'B':
consCount(input_string);
break;
case 'c':
case 'C':
cons_and_vowelCount(input_string);
break;
case 'd':
case 'D':
newString(input_string, LENGTH);
break;
case 'e':
case 'E':
exit(0);
default:
cout << endl << "Error: '" << choice << "' is an invalid selection" << endl;
break;
} //close switch
} //close do
while (not_done);
return 0;
} // close main
/* Function printmenu()
* Input:
* none
* Process:
* Prints the menu of query choices
* Output:
* Prints the menu of query choices
*/
void printmenu(void)
{
cout << endl << endl;
cout << "A) Count the number of vowels in the string" << endl;
cout << "B) Count the number of consonants in the string" << endl;
cout << "C) Count both the vowels and consonants in the string" << endl;
cout << "D) Enter another string" << endl;
cout << "E) Exit the program" << endl;
cout << endl << "Enter your selection: ";
return;
}
int vowelCount(char *str) {
char vowels[11] = "aeiouAEIOU";
int vowel_count = 0;
for (int i = 0; i < strlen(str); i++) {
for (int j = 0; j < strlen(vowels); j++) {
if (str[i] == vowels[j]) {
vowel_count++;
}
}
}
cout << "String contains " << vowel_count << " vowels" << endl;
return vowel_count;
} // close vowelCount
int consCount(char *str) {
char cons[43] = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
int cons_count = 0;
for (int i = 0; i < strlen(str); i ++) {
for (int j = 0; j < strlen(cons); j++) {
if (str[i] == cons[j]) {
cons_count++;
}
}
}
cout << "String contains " << cons_count << " consonants" << endl;
return cons_count;
} // close consCount
int cons_and_vowelCount(char *str) {
int cons = consCount(str);
int vowels = vowelCount(str);
int total = cons + vowels;
cout << "The string contains a total of " << total << " vowels and "
"consonants" << endl;
return total;
}
void newString(char *str, int len) {
cout << "Enter a string of no more than " << len-1 << " characters:\n";
cin.getline(str, len);
return;
}
The statement cin >> choice only consumes the character they type, not the carriage return that follows. Thus, the subsequent getline() call reads an empty line. One simple solution is to call getline() instead of cin >> choice and then use the first character as the choice.
BTW, the while (not done) should immediately follow the do { … }, and the return 0 is redundant. Also, you should call newString at the start of the program instead of repeating its contents.
cin >> choice leaves a newline in the input stream.. which cause the next getline() to consume it and return. There are many ways.. one way is to use cin.ignore() right after cin >> choice.
The cin >> choice only consumes one character from the stream (as already mentioned). You should add
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
right after cin>>choice to ignore all the characters that come into the stream after reading the choice.
p.s. #include <limits>