How to inverse string without library functions - C++ - c++

I'm having trouble with understanding how to output the inverse of the string then store the inverse value and apply it to a string variable to print the string later on. Some errors I receive depending on the structure of the program include : random characters being printed, just the string input being printed, the programming crashing... The program must be able to process this menu:
At one point I had the inverse working, but when I would add for example if(choice == '2') and create the reverse function it would start acting up again.
This is what I have for now :
int main()
{
string userString = "";
int i = 0;
char choice;
char invChar = char(userString[i]);
userString = invChar;
cout << "Please enter a word, a sentence, or a string of numbers." << endl;
getline(cin, userString);
do
{
cout << "\nUSE THIS MENU TO MAINPULATE YOUR STRING\n"
<< "----------------------------------------" << endl;
cout << "1) Inverse String\n"
<< "2) Reverse String\n"
<< "3) To Uppercase\n"
<< "4) Count Number Words\n"
<< "5) Count Consonants\n"
<< "6) Enter a Different String\n"
<< "7) Print the String\n"
<< "Q) Quit" << endl;
cin >> choice;
cin.ignore();
if (choice == '1')
{
for (int i = 0; i <= userString.length(); ++i)
{
if (isupper(userString[i]))
{
char(tolower(userString[i])); // if uppercase - converts to lower - if upper keeps value
invChar += userString[i];
}
userString = invChar;
}
cout << userString;
}
} while (choice != 'q' || choice != 'Q');
Thanks in advance for any tips and tricks!

Did you maybe mean to do this:
for (int i = 0; i < userString.length(); ++i)
{
if (isupper(userString[i]))
{
userString[i] = (tolower(userString[i]));
}
else if(islower(userString[i]))
{
userString[i] = (toupper(userString[i]));
}
}
This will actually inverse. What you were doing before doesn't work, and also only converts to uppercase

Related

How do I validate a string to make sure there is no non-digits and integers less than or equal to 1?

So I am currently working on a program in c++. I have written the following function. The line where it says "//code here" is where my issue is. Basically the program allows the user to create their own quiz txt file. For the question "How many questions should the quiz have?" the user will enter a number that represents the amount of questions. The issue arises when the user input will have to be validated.
Can anyone help me create a loop that does the following?
makes sure the user enters only numbers.
makes sure the numbers entered are greater than 1.
gives the user an error message if they entered a non digit.
gives the user an error message if they entered a number less than 2.
the program validates if the user just presses the enter key.
Once that is all sorted out the program will set NumberOfQuestions equal to the user input after converting it to an int.
void WriteOutQuestions(string &QuizName)
{
ofstream WriteOut;
string filename = "";
string userInput = "";
int numberOfQuestions;
char userInputChar = '0';
bool IncludeCommments = false;
cout << "Name your file\n";
getline(cin, filename);
cout << "Now give your new quiz a title\n";
getline(cin, QuizName);
cout << "How many questions should the quiz have?\n";
getline(cin, userInput);
//code here
numberOfQuestions = stoi(userInput);
cout << "The quiz will contain " << numberOfQuestions << " questions." << endl;
cout<< "Would you like to include comments in any of the choices?\n";
cout << "[Y/y for yes N/n for No]\n";
getline(cin, userInput);
if (userInput == "y" && userInput == "Y")
IncludeCommments = true;
else
cout << "Comments disabled by user...\n";
WriteOut.open(filename + ".txt");
if (!WriteOut)
{
cout << "The file was not found...\n";
}
else
{
cout << "File was read!\n";
}
WriteOut << QuizName << endl;
WriteOut << numberOfQuestions << endl;
for (int i = 0; i < numberOfQuestions; ++i)
{
cout << "What is question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "Q" << i + 1 << " " + userInput << endl;
cout << "What is choice A for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "A) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice A for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice B for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "B) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice B for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice C for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "C) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice C for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice D for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "D) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice D for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "Which choice is the right one? [A, B, C or D]\n";
getline(cin, userInput);
while (userInput != "a" && userInput != "A" && userInput != "b" && userInput != "B" &&
userInput != "c" && userInput != "C" && userInput != "d" && userInput != "D")
{
cout << "Only A-D is accepted\n";
}
userInputChar = userInput[0];
if (userInputChar > 96)
{
userInputChar -= 32;
}
userInput = userInputChar;
cout << "userinput contains " << userInput << endl;
cout << "userinputchar contains " <<userInputChar << endl;
WriteOut << userInput << endl;
}
WriteOut.close();
}
first of all you need to change the && in the below code to || to run the code the code correctly
if (userInput == "y" && userInput == "Y")
IncludeCommments = true;
else
cout << "Comments disabled by user...\n";
and coming to the validation you can maintain a flag variable after taking userinput
cout << "How many questions should the quiz have?\n";
getline(cin, userInput);
int length=userInput.length(); //gives the length of string entered
int flag=0; //flag variable
for(int i=0;i<length;i++)
{
if((!(userinput[i]>='0'&&userinput[i]<=9))||isspace(s[i])) //i am
considering space is not a problem
{
flag=1;
}
}
if(flag!=0)
{
cout<<"error:Non digit is entered"<<endl
}else
{
int numberofquestions = stoi(userinput);
if(numberofquestions<=1){
cout<<"error:number less than 2 is entered"<<endl;
}
}
There are so many options that it is difficult to make a good recommendation.
I will show you several solutions. The first part has always the same approach:
We run a do loop
First we instruct the user, what to do
Then we read the input
Then we, check, if all are digits
If we have all digits, then we convert to a number
and check, if the number is greater than 1
If we find an error, we loop again. Let`s look at the options in the code below
Index based for loop and compare with character digits
Index based for loop and use of isdigit function
Range based for loop and use of isdigit function
all_of algorithm and use of isdigit function
regex. Will also handle empty lines
Extened regex. Will also handle empty lines AND will check if number > 1
Options 1-4 need an additional check for an empty line. User presses just enter.
Please see code with all options:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
#include <regex>
int main() {
// We try to get input from the user and run a loop as long as it is not OK
bool inputIsOK{};
// This is the number of questions that we want to read
int numberOfQuestions{};
// Ask for valid input from user
do {
// Assume valid input
inputIsOK = true;
// Instruct user
std::cout << "\nHow many questions should the quiz have? Enter a number > 1.\n";
// Read complete line from the user
std::string line{};
if (std::getline(std::cin, line)) {
// Check, if all characters are valid (digits)
// Option 1 -------------------------------------------------------------------
// Index based for loop and compare with character digits
for (size_t i{}; i < line.length(); ++i) {
if (line[i] < '0' || line[i] > '9') {
inputIsOK = false;
std::cerr << "\nError 1: Please enter digits only\n";
break;
}
}
// Option 2 -------------------------------------------------------------------
// Index based for loop and use of isdigit function
for (size_t i{}; i < line.length(); ++i) {
if (not std::isdigit(line[i])) {
inputIsOK = false;
std::cerr << "\nError 2: Please enter digits only\n";
break;
}
}
// Option 3 -------------------------------------------------------------------
// Range based for loop and use of isdigit function
for (const char c : line) {
if (not std::isdigit(c)) {
inputIsOK = false;
std::cerr << "\nError 3: Please enter digits only\n";
break;
}
}
// Option 4 -------------------------------------------------------------------
// all_of algorithm and use of isdigit function
if (not std::all_of(line.begin(), line.end(), isdigit)) {
inputIsOK = false;
std::cerr << "\nError 4: Please enter digits only\n";
}
// Option 1-4 -----------------------------------------------------------------
// For option 1 to 4 you need to additionally check for empty line
if (inputIsOK && line.length() == 0) {
inputIsOK = false;
std::cerr << "\nError 5: Please enter digits only\n";
}
// Option 5 -------------------------------------------------------------------
// regex. Will also handle empty lines
if (not std::regex_match(line, std::regex("\\d{1,6}"))) {
inputIsOK = false;
std::cerr << "\nError 6: Please enter digits only (max 6)\n";
}
// Option 6 -------------------------------------------------------------------
// Extened regex. Will also handle empty lines AND will check if number > 1
if (not std::regex_match(line, std::regex(R"([2-9]|([1-9][0-9]{1,6}))"))) {
inputIsOK = false;
std::cerr << "\nError 7: Please enter number > 1 (Max 6 digits)\n";
}
// End Option -----------------------------------------------------------------
// Check, if number is > 1
if (inputIsOK) {
numberOfQuestions = std::stoi(line);
if (numberOfQuestions < 2) {
inputIsOK = false;
std::cerr << "\nError 8: Number too small. Enter number > 1\n";
}
}
}
else {
std::cerr << "\nError: General problem with input\n";
inputIsOK = false;
std::cin.clear();
}
} while (not inputIsOK);
return 0;
}
You can choose whatever option you want.
However. I would not use one of the above.
I would use the IOstream facilities and directly read an unsigned integer. If the input is wrong, the state of std::cin will goto fail and indicate the problem.
So, you could use that instead:
#include <iostream>
#include <limits>
int main() {
// We try to get input from the user and run a loop as long as it is not OK
bool inputIsOK{};
// This is the number of questions that we want to read
unsigned int numberOfQuestions{};
// Ask for valid input from user
do {
// Instruct user
std::cout << "\nHow many questions should the quiz have? Enter a number > 1.\n";
// Get input. Directly as number
inputIsOK = (std::cin >> numberOfQuestions) && (numberOfQuestions > 1);
// In case of error. Show message
if (not inputIsOK) {
std::cerr << "\nError 1: Wrong input\n";
std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (not inputIsOK);
return 0;
}
The ignore function will delete all the trash taht maybe still in the input buffer.

While loop in hangman program C++

while (wrongGuess != 6)
{
cout << "\nEnter a letter to guess: ";
cin >> wrongGuess;
wrongGuess = toupper(wrongGuess);
cout << "You guessed the letter: " << wrongGuess << endl;
for (int i = 0; i < fileWord.length(); i++)
{
if (fileWord[i] == wrongGuess)
{
cout << wrongGuess << " is in the letter to guess." << endl;
found = true;
}
}
// if not found - increment wrong guesses
if (!found)
{
wrongGuess++;
cout << wrongGuess << " is not in the word to guess." << endl;
}
//print the board that corresponds to the wrongGuess
}
the first part of the while loop is working it will display the " is in the word to guess." However when I enter an incorrect letter it does not display the " is not in the word to guess" instead it displays "You guessed the letter." What is wrong with my logic?
You are using wrongGuess as the input from the user as well as a counter for the wrong guesses...
Also, I do not know what are the types of wrongGuess and fileWord but my guess is you are comparing an int with a char which might not give the expected result.
I haven't tested this code at all, but it should set you on the way for how you design your program correct.
int guessedLetters = 0;
int guessLeft = 5;
while (guessLeft < 0 || guessedLetters == fileWord.length())
{
char guessInput;
cout << "\nEnter a letter to guess: ";
cin >> guessInput;
guessInput = toupper(guessInput);
cout << "You guessed the letter: " << guessInput<< endl;
for (int i = 0; i < fileWord.length(); i++)
{
if (fileWord[i] == guessInput)
{
cout << wrongGuess << " is in the letter to guess." << endl;
guessedLetters++;
found = true;
}
}
// if not found - increment wrong guesses
if (!found)
{
guessLeft--;
cout << guessInput << " is not in the word to guess." << endl;
}
//print the board that corresponds to the wrongGuess
}
I think you will need another variable, you are using the wrongGuess to control the while and read the input from the user.
I don't know, but try this.
int count = 0;
while (count != 6)
{
cout << "\nEnter a letter to guess: ";
cin >> wrongGuess;
wrongGuess = toupper(wrongGuess);
cout << "You guessed the letter: " << wrongGuess << endl;
for (int i = 0; i < fileWord.length(); i++)
{
if (fileWord[i] == wrongGuess)
{
cout << wrongGuess << " is in the letter to guess." << endl;
found = true;
}
}
// if not found - increment wrong guesses
if (!found)
{
count++;
cout << wrongGuess << " is not in the word to guess." << endl;
}
//print the board that corresponds to the wrongGuess
}

C++ getline forces to close a console application with space

The explanation:
Working with two input streams streams, both use getline() to capture the user input. The first getline() is called in the userStringPrompt() function:
string userStringPrompt()
{
string userString;
cout << "Enter a string: ";
getline(cin, userString);
return userString;
}
That sets a string that the program will use later to perform functions, like count its consonants, its vowels, etc.
The second input is used in the menu selection (choose what function/method to perform on the above string):
string userMenuPrompt()
{
string userString;
getline(cin, userString);
return userString;
}
This takes in a user input: A, B, C, D, E and performs an action. For example, if a user inputs into the first input stream:
Hello
and then enter "A" in the second input stream, it should count the vowels in hello, then return the number from the calculation, e.g. 2
The issue:
The program functions correctly when the input in userStringPrompt is without spaces. For example, Hello works, but Hello World would break the application and cause a force close. I'm not sure why, since I am capturing the stream with getline(cin, string).
The entire code:
#include <string>
#include <iostream>
using namespace std;
string userStringPrompt();
string userMenuPrompt();
void showMenu();
int countConsonants(string *ptr);
int countVowels(string *ptr);
int countConsonantsVowels(string *ptr);
int main()
{
string userInput = "";
string userString;
bool userStringSet = false;
while (userInput != "e") {
if (!userStringSet) {
userString = userStringPrompt();
userStringSet = true;
}
showMenu();
userInput = userMenuPrompt();
string *pointerVariable = &userString;
if (userInput == "a") {
cout << endl;
cout << "Vowel count in \"" << userString << "\": " << countVowels(pointerVariable) << endl;
cout << endl;
break;
}
if (userInput == "b") {
cout << endl;
cout << "Consonants count in \"" << userString << "\": " << countConsonants(pointerVariable) << endl;
cout << endl;
break;
}
if (userInput == "c") {
cout << endl;
cout << "Vowel count in \"" << userString << "\": " << countVowels(pointerVariable) << endl;
cout << "Consonants count in \"" << userString << "\": " << countConsonants(pointerVariable) << endl;
cout << endl;
break;
}
if (userInput == "d") {
userStringSet = false;
break;
}
}
return 0;
}
int countConsonants(string *ptr) {
string getVar = *ptr;
int stringSize = getVar.length();
int vowelCount = countVowels(ptr);
int totalConsonants = stringSize - vowelCount;
return totalConsonants;
}
int countVowels(string *ptr) {
int vowelsToCount = 0;
string stringVar = *ptr;
for (int i = 0; i < stringVar.length(); i++){
if (tolower(stringVar[i]) == 'a' || tolower(stringVar[i]) == 'e' || tolower(stringVar[i]) == 'i' || tolower(stringVar[i]) == 'o' || tolower(stringVar[i]) == 'u') {
vowelsToCount++;
}
}
return vowelsToCount;
}
int countConsonantsVowels(string *ptr) {
int count = countConsonants(ptr);
count += countVowels(ptr);
return count;
}
string userStringPrompt()
{
string userString;
cout << "Enter a string: ";
getline(cin, userString);
return userString;
}
string userMenuPrompt()
{
string userString;
getline(cin, userString);
return userString;
}
void showMenu() {
cout << "A) Count the number of vowels in the stream" << endl;
cout << "B) Count the number of consonants in the stream" << endl;
cout << "C) Count both the vowels and consonants in the stream" << endl;
cout << "D) Enter another string" << endl;
cout << "E) Exit the program" << endl;
}
Any guidance/hints would be greatly appreciated. I'm absolutely confused.
I guess your program is not crushing, it's just normally exits.
The program '[8776] Chapter10.exe' has exited with code 0 (0x0).
which is ok, no error code returned.
When you run your program it asks for input, do its work and because there is no more work for it - exits. To see the output you can do one of the following:
Try to run it with Ctrl + F5 in VS, it will add pause command to the end.
Another way to run it is to open command line and run it from there.
Also in your case I guess the problem is in break statements. When you choose what to do with the string you break your loop (which should run while user enters e). Remove all breaks and it will be fine.

why am i getting so many numbers from my array c++

I'm still working on this project and I have most of my problems fixed.
The problem shows itself while using selection B, but lies in option A and sending the array to the .txt file. There are a lot of extra numbers being added to the .txt file. When I cout, it displays the numbers in the array like it should, but in the text file it looks like this
Anthony201910181114-8589934604445358131768008182078541176802418196927161130726102120444535893
everything before the - is correct, but all of these numbers after need to go.
Why is this happening and how can I fix this?
Thank you.
int main()
{
int Stats[6];
char Selection;
string Character1;
int i;
char keep;
do
{
cout << "Hello, welcome to my character generator. Please select an option" << endl;// Menu Options
cout << "A: Create Character Name and generate stats" << endl;
cout << "B: Display Name and Stats" << endl;
cout << "C: Quit" << endl;
cin >> Selection; // Menu Selection
cout << endl;
if ( (Selection == 'a') || (Selection == 'A') )// if user selects a, this happens
{
cout << "Welcome, Before you can start your adventures you must name your character." << endl;
do
{
cout << "Please enter your a name." << endl;// prompts user to enter a name for their Caracter
cin >> Character1;
cout << "Thank you now lets generate your stats." << endl;
for (i=0; i<6;i++)// I Want this to run the function GenerateScore() 6 times and input each result into the next element of Stats[6]
{
Stats[i]=GenerateScore();
}
for(i=0;i<6;i++)// displays your scores to the player.
{
cout << Stats[i]<< endl;
}
cout << "would you like to keep this name and these Stats?"<< endl;
cout << "Y/N" << endl;
cin >> keep;
break;
}
while ( (keep=='n') || (keep=='N') );
ofstream savecharinfo("charactersave.txt");// saves the Name and the filled array Stats[6] to the charactersave.txt file
if(savecharinfo.is_open())
{
savecharinfo << Character1;
for(int i = 0; i<6; i++)
{
savecharinfo << Stats[i];
}
}
else cout << "File could not be opened." << endl;
}
else if ( (Selection =='b') || (Selection == 'B') )
{
cout << " Welcome back, here are is your character." << endl;
ifstream displaycharacter("charactersave.txt");
if(displaycharacter.is_open())
{
while ( getline (displaycharacter,Character1) )
{
cout << Character1 << endl;
}
displaycharacter.close();
}
else cout << "File could not be opened";
}
else
break;
}
while ( (Selection != 'c') || (Selection == 'C') ); // ends the program is c or C is entered.
return 0;
}
int GenerateScore()
{
int roll1 = rand()%6+2;
int roll2 = rand()%6+2;
int roll3 = rand()%6+2;
int sum;
sum=roll1+roll2+roll3;
return sum;
}
Like was mentioned in the comments:
while ( (keep='n') || ('N') );
should (at least) be changed to
while ( (keep == 'n') || (keep == 'N') );
Also, this loop:
for(int i = 0; Stats[i]; i++)
Will only terminate when Stats[i] evaluates to false, which will only happen when Stats[i] == 0. This loop is causing the extra chars in the file: the code keeps accessing out of bounds array elements until randomly the out of bounds element == 0. You probably want for(int i = 0; i < 6; i++)

Get blank line after calling Palindrome function

So I have these two functions at the top of my program:
string deletespaces(string sentence){
sentence.erase(std::remove(sentence.begin(), sentence.end(), ' '), sentence.end());
return sentence;
}
and
string checkpalindrome(string sentence){
deletespaces(sentence);
if (sentence == string(sentence.rbegin(), sentence.rend())){
cout << sentence << " is a palindrome." << endl;
}
if(sentence != string(sentence.rbegin(), sentence.rend())){
cout << sentence << " isn't a palindrome." << endl;
}
}
This is my main body of code.
int main(){
int x = 1;
string originalsentence;
while (x == 1) {
int a = 1;
int input;
string sentence;
cout << "Press 1 to reverse a string, 2 to check a palindrome, and anything else to quit: ";
cin >> input;
if(input == 1) {
cout << "Enter a sentence to reverse: ";
cin.ignore();
getline(cin,originalsentence);
originalsentence = sentence;
cout << string(sentence.rbegin(), sentence.rend()) << endl;
}
if(input == 2) {
cout << "Enter a sentence to check: ";
cin.ignore();
getline(cin,originalsentence);
originalsentence = sentence;
checkpalindrome(sentence);
}
cout << "Hit 1 if you want to continue, anything else to quit: ";
cin >> x;
}
}
So here is my problem. I am able to put in my choice about whether to reverse a string or check whether the string is a palindrome. However, when I try to reverse the string, it simply gives a blank line, then asks whether I want to continue. When I ask to check a palindrome, it simply says "is a palindrome" regardless of what I input. Any ideas?