The following code produces an infinite loop when I enter 2 cstrings of entirely 1s and 0s.
What have I done?
char input1[9] = {'\0'};
char input2[9] = {'\0'};
bool reEnter = false;
do
{
reEnter = false;
cout << "The numbers to be added are: "<< endl;
cin.ignore();
cin.getline(input1, 9, '\0');
cin.ignore();
cin.getline(input2, 9, '\0');
for (int i = 0; i<8; i++)
{
if((input1[i] != '0') && (input1[i] != '1') || (input2[i] != '0') && (input2[i] != '1'))
{
reEnter = true;
}
}
if(reEnter == true)
cout << "Must be an 8 bit binary" << endl;
}while(reEnter == true);
This got it. For some reason it didn't like the ignores, and terminating the cin.getline functions with null characters was creating the infinite loop.
char input1[9] = {'\0'};
char input2[9] = {'\0'};
bool reEnter = false;
do
{
reEnter = false;
cout << "The numbers to be added are: "<< endl;
cin.getline(input1, 9);
cin.getline(input2, 9);
for (int i = 0; i<8; i++)
{
if((input1[i] != '0') && (input1[i] != '1') || (input2[i] != '0') && (input2[i] != '1'))
{
reEnter = true;
}
}
if(reEnter == true)
cout << "Must be an 8 bit binary" << endl;
}while(reEnter == true);
Related
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 6 months ago.
Improve this question
I am making a program to calculate the value of words for a friend who is interested in numerology.
In my program, I ask the user how many words they want to calculate, so I can dynamically allocate the size of the array to store the words.
It works perfectly the first time they run the program, but when I ask if they want to test more words, and if they hit yes, it reruns the while loop and it asks them for how many words to evaluate, but this time, no matter what number they type, it always sets the size of the array to 1, due to the number variable being set to 1 and not changing after user input. My friend has to rerun the program to make it work again.
I really want to fix this problem to make it easier for my friend.
(Yes, I do plan on fixing my code, and if you have seen this code in another question, that was me, and yes, I am going to improve my code based on the suggestions I got, but I want it to at least work before I improve on it.)
Here is my code:
#include <iostream>
#include <string>
#include <sstream>
void clear()
{
system("clear");
}
int main(int argc, char* argv[])
{
int number{1};
int total{0};
int value{0};
std::string number_str;
std::string response;
std::stringstream ss;
bool isDigit;
while (true)
{
clear();
number = 1;
total = 0;
value = 0;
number_str = "";
response = "";
isDigit = true;
clear();
std::cout << "How many words to evalute? (Default: 1):\n> ";
//std::cin >> number;
std::getline(std::cin, number_str);
//std::cin.ignore();
clear();
for (int i = 0; i < number_str.size(); ++i)
{
if (!(std::isdigit(number_str[i])))
isDigit = false;
break;
}
if (isDigit)
{
if (number_str.empty()) {
number = 1;
} else {
ss << number_str;
ss >> number;
}
}
if (std::isdigit(number)) {
if (number <= 0) {
number = 1;
}
}
std::string* pPhrase = new std::string[number];
int* pValue = new int[number]{}; // Initialized each element to 0
for (int i = 0; i < number; ++i) // could replace "number" with "sizeof(pPhrase)/sizeof(pPhrase[0])"
{
(i == 0) ? std::cout << "Enter Word #" << i+1 << " (or type your full phrase):\n> " :
std::cout << "Enter Word #" << i+1 << ":\n> ";
std::cin >> pPhrase[i];
for (char j : pPhrase[i])
{
value = 0;
if (std::isalnum(j) && j != '0')
{
if (std::isalpha(j))
j = std::tolower(j);
} else {
continue;
}
if (j == 'a' || j == 'i' || j == 'j'
|| j == 'q' || j == 'y' || j == '1')
value += 1;
if (j == 'b' || j == 'k' || j == 'r' || j == '2')
value += 2;
if (j == 'c' || j == 'g' || j == 'l'
|| j == 's' || j == '3')
value += 3;
if (j == 'd' || j == 'm' || j == 't' || j == '4')
value += 4;
if (j == 'e' || j == 'h' || j == 'n'
|| j == 'x' || j == '5')
value += 5;
if (j == 'u' || j == 'v' || j == 'w' || j == '6')
value += 6;
if (j == 'o' || j == 'z' || j == '7')
value += 7;
if (j == 'f' || j == 'p' || j == '8')
value += 8;
pValue[i] += value;
value = 0;
std::cout << '\n';
clear();
}
}
std::cin.ignore();
std::cin.clear();
std::cout << "\n\n";
for (int i = 0; i < number; ++i)
{
std::cout << "Value of \"" << pPhrase[i] << "\": " << pValue[i] << '\n';
total += pValue[i];
}
std::cout << "Total value: " << total << "\n\nPress \'Enter\' or \'Return\' to Continue... ";
//std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
//std::cin.clear();
std::cout << "\n\n\nWould you like to evaluate another phrase? (Y/n):\n> ";
std::getline(std::cin, response);
delete[] pPhrase;
delete[] pValue;
if (response[0] == 'y' || response[0] == 'Y'
|| response.empty() || response[0] == ' ')
continue;
break;
}
std::cout << "Exiting...";
try {
//system("killall Terminal");
} catch (std::exception& ex) {}
std::cout << "\n\n\n";
return 0;
}
for (int i = 0; i < number; ++i) // could replace "number" with "sizeof(pPhrase)/sizeof(pPhrase[0])"
Actually, you can't use the sizeof(array)/sizeof(array[0]) trick on a pointer to an array. It only works when you use it directly on the actual array itself. There are numerous questions on StackOverflow that explain this, including (just to name a few):
How to get the size of an array using a pointer to the first element and properties of "\0"?
Pointer to an array get size C++
getting size of array from pointer c++
In any case, one problem I do see in your code is that on each iteration of the outer while loop, you are not resetting the std::stringstream that you use to convert the user's input to the number variable. Each iteration is just pushing more and more data into the stream without removing the old data first.
Also, using std::isdigit(number) is useless. You already validated the user entered only digits, and then converted those digits to the number variable. What you didn't do is validate that the conversion to int was actually successful before using number. You must validate that the extraction of the number from the stringstream is successful, ie in case the user enters a large value that can't fit into an int.
Try this instead:
while (true)
{
clear();
number = 1;
total = 0;
value = 0;
number_str = "";
response = "";
isDigit = true;
// ADD THIS!
ss.str("");
ss.clear();
//
...
if (isDigit)
{
ss << number_str;
if (!(ss >> number) { // <-- ADD THIS!
number = 1;
}
}
...
}
That being said, you could just get rid of the stringstream altogether, you don't actually need it. You can extract the number value directly from std::cin itself (which you are already aware of, because you commented out that code), eg:
std::cout << "How many words to evalute? (Default: 1):\n> ";
if (!(std::cin >> number)) {
number = 1;
std::cin.clear();
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// no need for the `isdigit() check at all...
Hi i keep getting a stack around the variable nhour was corrupted error, and I can not figure out why. I am trying to have a time entered and check it to make sure it is a good input. making the array bigger or smaller seems not to work. I have also added checks in and the output seems find until I get the error
void DEPARTURETIME(string& szdepartureTime)
{
bool berror;
char cdeparture[9];
int nhour[2],
nminute[2],
nhourValue,
nminuteValue;
nhour[0] = 0;
do
{
berror = false;
system("CLS");
cout << "Enter departure time. (HH:DDAM/PM)" << endl;
cin >> cdeparture;
cin.ignore();
berror = ERRORCHECK();
for (int i = 0; i < 2 && berror != true; i++)
{
nhour[i] = CONVTOINT(cdeparture[i]);
}
//Beginning of testing hour for errors
if (nhour[0] > 1 && berror != true)
{
cout << "Error, can not exceed 12 hours." << endl;
system("pause");
berror = true;
}
else if (nhour[0] == 1)
{
nhour[0] *= 10;
}
cout << nhour[0] << nhour[1] << endl;
nhourValue = nhour[0] + nhour[1];
cout << nhourValue << endl;
if (nhourValue > 12 || nhourValue <= 0 && berror != true)
{
cout << "Error, can not exceed 12 hours and can not be
zero." << endl;
system("pause");
berror = true;
}
//End of testing hour for errors
//Beginning of testing for a colon
if (cdeparture[2] != ':' && berror != true)
{
cout << "Error, you need a colon inbetween hours and minutes." << endl;
system("pause");
berror = true;
}
//End of testing for a colon
for (int i = 3; i < 5 && berror != true; i++)
{
nminute[i] = CONVTOINT(cdeparture[i]);
}
//Beginning of testing for minute errors
if (nminute[3] > 6 && berror != true)
{
cout << "Error, minutes can not exceed 60." << endl;
system("pause");
berror = true;
}
else if (nminute[3] > 0 || berror != true)
{
nminute[3] *= 10;
}
nminuteValue = nminute[3] + nminute[4];
if (nminuteValue > 60 && berror != true)
{
cout << "Error, minutes can not exceed 60." << endl;
system("pause");
berror = true;
}
//End of testing for minute errors
cdeparture[5] = toupper(cdeparture[5]);
cdeparture[6] = toupper(cdeparture[6]);
//Beginning of testing for AM and PM errors
if (cdeparture[5] != 'A' && cdeparture[5] != 'P' || cdeparture[6] != 'M' && berror != true)
{
cout << "Error, must have AM or PM." << endl;
system("pause");
berror = true;
}
} while (berror != false);
//End of testing for AM and PM errors
for (int i = 0; i < 7; i++)
{
szdepartureTime += cdeparture[i];
}
return;
}
and this is the other function that is called
int CONVTOINT(char cchar)
{
int value = cchar - '0';
if (value < 0 || value > 9)
{
cout << "Error, Convertion failed" << endl;
system("pause");
return 0;
}
return value;
}
You declare nminute as an array with two elements, but when you use it you're accessing elements 3 and 4 (which requires the array to have 5 elements). Since you're accessing past the ends of the array, you run into Undefined Behavior. In this case, your compiler has inserted code to detect this problem and is telling you about it.
To fix it, change the subscripting on nminute when used in the code to only access elements 0 and 1.
Write a program using for loop which stores alphabets from Z-A. Extract only vowels from this array and store them into another array vowels. Now display these vowels using for loop from vowels array.
My output is not working properly. If I write my name without spaces like abdulhananhamid, then it works and shows a u a a.
I do not know how to use cin in a for loop, either.
#include<iostream>
#include<conio.h>
using namespace std;
int vowel (char x);
int main()
{
char size=100;
char x[size];
char A[5];
int n,i,;
cout<<"Enter any string\n";
cin>>x;
for (i = 0, n = 0; i<size; i++)
if (vowel(x[i]))
A[n++] = x[i];
for (n = 0;n<5;n++)
cout << A[n] << " ";
getch();
return 0;
}
int vowel(char x)
{
if(x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
return 1;
else
return 0;
}
This looks like a good assignment for using std::string and std::getline.
std::string user_text;
std::cout << "Enter a string: ";
while (std::getline(std::cin, user_text)
{
const size_t length = user_text.length();
std::string vowels;
for (size_t i = 0; i < length; ++i)
{
const char c = user_text[i];
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u'))
{
vowels += c;
}
}
std::cout << "Vowels found: " << vowels << "\n";
std::cout << "\nEnter a string: ";
}
If you must use character arrays, you should check for overflow:
unsigned int MAXIMUM_CHARACTERS = 128;
char user_text[MAXIMUM_CHARACTERS];
char vowels_found[MAXIMUM_CHARACTERS];
std::cout << "Enter a string: ";
while (std::cin.getline(&user_text[0], MAXIMUM_CHARACTERS))
{
unsigned int vowel_index = 0U;
const size_t length = strlen(user_text);
for (size_t i = 0; i < length; ++i)
{
const char c = user_text[i];
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u'))
{
vowels_found[vowel_index++] = c;
}
}
vowels_found[vowel_index] = '\0';
std::cout << "Vowels found: " << vowels_found << "\n";
std::cout << "\nEnter a string: ";
}
A function for checking for a vowel could look like:
bool is_vowel(char c)
{
return (c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u');
}
I am suppose to create a program such that when 'y' is entered it will execute the code in the first do-while loop. however, when 'y' is entered it just skips over the chunk of codes!
Enter a phone symbols:
a
2
Continue (Y/y): y
Enter a phone symbols:
Continue (Y/y):
Is there anyway I can solve this without using cin.ignore as it changes the layout. Thanks in advance!
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <iomanip>
#include <cstring>
const int MAX = 100;
using namespace std;
int getInt(char);
bool isValidChar(char);
int main()
{
int num;
int j = 0;
char name, conti;
char alpha[MAX];
do {
cout << "Enter a phone symbols: " << endl;
cin.getline(alpha, MAX);
// cin.ignore(100, '\n');
while (alpha[j] != '\0')
{
name = alpha[j];
if (isValidChar(name) == true)
{
num = getInt(name);
if (num == -1)
{
cout << "-";
}
else
{
cout << num;
}
}
else
{
cout << " - Invalid Char " << name << " found - rejected";
}
j++;
} // end while
cout << endl;
do {
cout << "\nContinue (Y/y): ";
cin >> conti;
cout << "\n" << endl;
conti = tolower(conti);
if (conti == 'n')
{
exit(0);
}
} while (conti != 'n' && conti != 'y');
} while (conti == 'y');
}
int getInt(char input)
{
int result;
char value;
value = tolower(input);
if ((value >= 'a' && value <= 'c'))
{
result = 2;
}
else if ((value >= 'd' && value <= 'f'))
{
result = 3;
}
else if ((value >= 'g' && value <= 'i'))
{
result = 4;
}
else if ((value >= 'j' && value <= 'l'))
{
result = 5;
}
else if ((value >= 'm' && value <= 'o'))
{
result = 6;
}
else if ((value >= 'p' && value <= 's'))
{
result = 7;
}
else if ((value >= 't' && value <= 'v'))
{
result = 8;
}
else if ((value >= 'w' && value <= 'z'))
{
result = 9;
}
else if (value == ' ')
{
result = -1;
}
return result;
}
bool isValidChar(char value)
{
if (isalpha(value) || value == ' ')
{
return true;
}
else
{
return false;
}
}
What do you mean as: Is there anyway I can solve this without using cin.ignore as it changes the layout.?
Your layout is contolled, basicly by this line:
cout << "\nContinue (Y/y): ";
cin >> conti;
cout << "\n" << endl; // <-- this one
conti = tolower(conti);
If you supress it, there will be no empty line. Otherwise, if you change it to
cout << endl;
Just one empty line.
The full code I am using is listed below, it is supposed to simulate a game of craps and print details to the user and allow for betting if the user desires it. Everything functions except for the actual craps game. Instead of looping only while there is not a truth value associated to crapsResult, it finds one real value and an incomprehensible string of a single negative number. Any help would be appreciated.
int main()
{
//Declare the user input variables
int gamesPlayed = 0;
char inputPrint = ' ';
char isBetting = ' ';
int startingBet = 0;
//Declare the variables used by the program
int endingBet = 0;
int currentGame = 0;
bool crapsResult;
int gamesWon = 0;
int gamesLost = 0;
double percentWon = 0;
bool detailPrint = false;
//Prompt the user to input their variables
cout << "Enter the number of games to be played: ";
cin >> gamesPlayed;
while(gamesPlayed < 1)
{
cout << " Error: must be greater than 0" << endl;
cout << "Enter the number of games to be played: ";
cin >> gamesPlayed;
cin.clear();
cin.ignore();
}
cout << "Do you wish to print details (Y/N): ";
cin >> inputPrint;
if(inputPrint == 'y' || inputPrint == 'Y')
{
detailPrint = true;
}
cout << "Do you wish to bet (Y/N): ";
cin >> isBetting;
if(isBetting == 'y' || isBetting == 'Y')
{
cout << "Enter money to start betting with: ";
cin >> startingBet;
while(startingBet < 1)
{
cout << " Error: must be greater than 0" << endl;
cout << "Enter the number of games to be played: ";
cin >> gamesPlayed;
cin.clear();
cin.ignore();
}
}
//Seed the random number generator
srand(time(NULL));
//Set a value for ending bet
if(startingBet == 0)
{
endingBet = 1;
}
else
{
endingBet = startingBet;
}
//Call playcraps to simulate the game for as many games as the user input
for(currentGame = 1; currentGame <= gamesPlayed && endingBet > 0; currentGame += 1)
{
crapsResult = NULL;
crapsResult = playCraps(currentGame, detailPrint, isBetting, startingBet);
if(crapsResult == true)
{
gamesWon += 1;
endingBet = betting(endingBet, crapsResult);
}
if(crapsResult == false)
{
gamesLost += 1;
endingBet = betting(endingBet, crapsResult);
}
if((isBetting == 'Y' || isBetting == 'y') && (detailPrint == true))
{
cout << "Money left is $" << endingBet << endl;
}
}
//Calculate the percentage of games won
percentWon = (double(gamesWon) / double(currentGame-1)) * 100.0;
//Print the results to the user
if(isBetting == 'Y' || isBetting == 'y')
{
cout << "Money at end of games is $" << endingBet << endl;
}
cout << "The number of games played is " << currentGame - 1 << endl;
cout << "The number of games won is " << gamesWon << endl;
cout << "The number of games lost is " << gamesLost << endl;
cout << "The percent of games won is " << fixed << showpoint << setprecision(3) << percentWon << endl;
}
//Simulates the roll of a single die and returns the result
int roll()
{
int rollResult = 0;
rollResult = rand() % 6 + 1;
return rollResult;
}
//Calls roll twice and returns the sum of the two results
int roll2Dice()
{
//Declare variables for this function
int rollOne = 0;
int rollTwo = 0;
int rollSum = 0;
//Find rollOne and rollTwo
rollOne = roll();
rollTwo = roll();
//Find rollSum
rollSum = rollOne + rollTwo;
return rollSum;
}
bool playCraps(int currentGame, bool detailPrint, char isBetting, int startingBet)
{
bool crapsResult = NULL;
int currentGameStorage[100];
int currentRoll = 1;
int point = roll2Dice();
int printingNumber = 0;
currentGameStorage[0] = point;
if(point == 7 || point == 11)
{
crapsResult = true;
}
else if(point == 2 || point == 3 || point == 12)
{
crapsResult = false;
}
else
{
crapsResult = NULL;
}
while(crapsResult != true && crapsResult != false)
{
currentGameStorage[currentRoll] = roll2Dice();
if(currentGameStorage[currentRoll] == point)
{
crapsResult = true;
}
else if(currentGameStorage[currentRoll] == 7)
{
crapsResult = false;
}
currentRoll += 1;
}
if(detailPrint == true)
{
cout << "Game " << currentGame << ": ";
for(printingNumber = 0; printingNumber <= currentRoll; printingNumber += 1)
{
cout << currentGameStorage[printingNumber] << " ";
}
if(crapsResult == true)
{
cout << "win";
}
else if(crapsResult == false)
{
cout << "lose";
}
cout << endl;
}
return crapsResult;
}
int betting(int endingBet, bool crapsResult)
{
if(crapsResult == true)
{
endingBet += 1;
}
else if(crapsResult == false)
{
endingBet -= 1;
}
return endingBet;
}
Just skimmed and didn't read all of your code (so there may be other things wrong too), but this line is definitely problematic:
while(crapsResult != true && crapsResult != false)
It is logically impossible for crapsResult to simultaneously be both true and false, so that loop will never be entered.
Turix got the right bug I believe, but I would put the emphasis on a different spot:
bool crapsResult = NULL;
You are trying to use crapsResult for three different values (true, false and NULL). However, NULL usually has a integer value of 0, which translates to a boolean value of false, so your loop will never be entered.
Then a second bug comes into play: currentRoll is 1 at this time, so you try to print the contents of currentGameStorage from index 0 to 1 (inclusive), currentGameStorage[1] hasn't been assigned yet. This is why you get the cryptic numer in your output. This is a general mistake: Your code always tries to print one item too much. Use < instead of <= in the loop head to fix that:
for(printingNumber = 0; printingNumber < currentRoll; printingNumber += 1)