C++ Debug Assertion Failed, Invalid Null Pointer - c++

I've looked everywhere, but I cannot find a solution to exactly why this happens in my situation.
I'm making a simple string function that asks for a string, and prints out the length.
However, I get an "Invalid Null Pointer" assertion error when I run the compiled version. I have had no errors when compiling, but the error comes up when I run it.
This is the function causing the problem:
string getString()
{
string wordInput;
cout << "Enter a word that has AT LEAST four (4) letters! ";
getline(cin, wordInput);
while (wordInput.length() <= 3)
{
cout << "Enter a word that has AT LEAST four (4) letters! ";
getline(cin, wordInput);
}
return 0;
}
The while loop isn't a problem. I commented it out and I still got the same error. How is initializing word input, cout, and getline giving me the error?
Here is my whole code so far (not finished). I tried running the string by itself too, the getKeyLetter function isn't a problem.
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
char getKeyLetter()
{
char keyLetter;
string convertFromString;
cout << "Enter a SINGLE character! ";
getline(cin, convertFromString);
while (convertFromString.length() > 1)
{
cout << "Enter a SINGLE character! ";
getline(cin, convertFromString);
}
assert(convertFromString.size() == 1);
keyLetter = convertFromString[0];
return 0;
}
string getString()
{
string wordInput;
cout << "Enter a word that has AT LEAST four (4) letters! ";
getline(cin, wordInput);
while (wordInput.length() <= 3)
{
cout << "Enter a word that has AT LEAST four (4) letters! ";
getline(cin, wordInput);
}
return 0;
}
int main()
{
getKeyLetter();
getString();
return 0;
}

First, in your GetKeyChar() function, writing:
char ch;
cout << "Enter a single character: ";
cin >> ch;
will give you the first character the person types into the command prompt. So, typing "check" will have ch = c.
Second, as eran said, at the end of your functions, you have
return 0;
Unless you want both functions to return a char and string respectively, make them void GetKeyLetter() and void GetString(). Or, if you do want to return something, have them return ch (from my example) and return wordInput.
Only int main(), per standard, needs return 0, to show you that it exited correctly. the variable type you put in front of your functions is what variable you plan on returning. 0 is an int, so that's what it returns based on convention. As was pointed out, a return is not necessary in main. If you want your functions to return values, do this in your main.
string str;
char ch;
ch = GetKeyLetter();
str = GetString();
return 0;
And have your functions return the char and string value you want them to.

Related

Comparing char array in c++

I need help in c++. I want to compare char array. So, I did some coding. Unfortunately, it always comes out an error. I can't run it. Here I attached the code. Please help me fix this code. I want to check if the conclusion equal to sentence 1 then it is invalid but if it's not equal sentence 1 then it is valid. Help me, please. Thank you.
int number;
char sentence[number];
char rules[50];
char statement[50];
char premis1[100];
char premis2[100];
char conclusion[100];
cout<<"How many sentence you want to insert:";
cin>>number;
cout<<endl;
for(int i=0; i<number; i++)
{
cout<<"Enter sentence ";
cout<<i+1;
cout<<":";
cin>>sentence[i];
cin.ignore();
}
cout<<"Enter premis 1:";
cin.getline(premis1,100);
cin.ignore();
cout<<"Enter premis 2:";
cin.getline(premis2,100);
cin.ignore();
cout<<"Enter conclusion:";
cin.getline(conclusion,100);
cin.ignore();
for(int i=0;i<number;i++)
{
if(strcmp(conclusion,sentence[0],)==0)
{
cout<<"Statement is invalid."<<endl;
cout<<endl;
}
else if(strcmp(conclusion,sentence[0])!=0)
{
cout<<"Statement is valid."<<endl;
}
else
cout<<"exit"<<endl;
}
Your mistakes you've made in the program:
You never initialized number but used in sentence[], still it's invalid even after number's declaration, that's because the compiler must know the exact value of the array length to be defined.
You've defined sentence as a char array but from your code, it seems like you wanted to store a full sentence into each element of array, which is impossible. Use std::string here.
You're doing strcmp() with the first character of char array, not the sentence with conclusion.
Aside: Please don't forget to include the important header files which are common to the code and we must assume your program is incomplete, because it has a lack of main() and statement(s), such as strcmp(...,...',' - incomplete).
Redesigned the program (notice that using namespace std statement is used here because it's just a small program to demonstrate and for sake of simplicity and getting rid of std:: prefixes everywhere):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(void) {
int number = 0;
vector<string> sentence;
string tempSentence;
string conclusion;
cout << endl;
cout << "How many sentences you want to insert? ";
cin >> number;
for (int i = 0; i < number; i++) {
fflush(stdin);
cout << "Enter sentence " << (i + 1) << ": ";
getline(cin, tempSentence);
sentence.push_back(tempSentence);
}
cout << "Enter conclusion: ";
getline(cin, conclusion);
if (conclusion == sentence[0])
cout << "The statement is invalid." << endl;
else if (conclusion != sentence[0])
cout << "The statement is valid." << endl;
else
cout << "EXIT" << endl;
return 0;
}
I've taken std::vector<> of std::string here to insert a single string in defined number of sentences given in a dynamic way in each iteration (from #include <vector>) and used std::string rather than char arr[], it's easy to compare strings here.
Sample Output:
$ g++ -o prog prog.cpp; ./prog
How many sentences you want to insert? 3 // --- INPUT
Enter sentence 1: This is the first sentence.
Enter sentence 2: This is the second sentence.
Enter sentence 3: This is the third sentence.
Enter conclusion: This is NOT the first sentence.
The statement is valid. // first sentence != conclusion // --- OUTPUT

Assigning the "Enter Key" value to a string [C++]

In this rather simple exercise I have to receive an user input, store said input into a string, pass the string to a function by reference and finally modify the string so that every character is "parsed" by the toupper() function.
However, should the user insert 'q' as input, the program stops saying "Bye" OR if he just presses the Enter Key, the program is supposed to say something like "Hey, this string is empty".
Now the real problem here is in the last part since my code won't manage the case where the user inputs only the Enter Key value (to be honest, even if I just text a bunch of spaces followed by the Enter Key, nothing happens)
void uppercase(std::string &);
int main(){
using namespace std;
string ex2;
cout << "Exercise 2" <<endl;
while(ex2!="Bye"){
cout << "Enter a string(q to quit): ";
cin >> ex2;
cout << "Was: " << ex2 << endl << "Now is: ";
uppercase(ex2);
}
return 0;
}
void uppercase(std::string &str){
using namespace std;
if(str[0]=='\n')
cout <<"Empty string dude!" << endl;
else{
if(str.length()==1 && str[0]=='q'){ //press 'q' to exit program
str="Bye";
cout << str;
}
else{ //uppercase
for(int i=0;i<str.length();i++){
str[i]=(toupper(str[i]));
}
cout << str <<endl;
}
}
}
I also tried the compare() function and even to compare the whole string to null (pointless, but still worth a shot) and to the string "";
Sorry for the bad interpretation of your problem, trying
if( (str.length()==1 && str[0]=='q') || str.length() == 0)
{}
May help you out of the problem

Converting char to int when asked to enter an integer and checked with isdigit

So recently, I came across using isdigit as a way to check to see if an entered value for an int is actually an integer, rather than a string or a char.
However, when I wrote a short program to play around with that, the program failed to execute from that point on.
EDIT: I also in the program wanted to take the invalid data and convert it to a different data type.
Here is the code:
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
int enterCFN;
char revisit;
int review(0);
cout << "Enter a digit: ";
cin >> enterCFN;
bool y = isdigit(enterCFN);
if (y == false)
{
// This is the data conversion section
revisit = enterCFN;
revisit = review;
cout << review << "\n";
}
else
{
cout << enterCFN << "\n";
}
return 0;
}
Is there anyone who can correct my error and show me what I'm doing wrong?
enterCFN is an int. It stores a number. isdigit() checks if a character represents a number. These are not the same thing: for example 32 is a number but char(32) means ' ' (space).
What you want instead is this:
if (cin >> enterCFN)
That will take the input from the user and check if it is valid all at once. No need for isdigit().
isdigit() checks if a given character is one of 0-9
For validating integer do something like following:
std::cout << "Enter a digit: ";
std::cin >> enterCFN ;
while (1)
{ if ( std::cin >> enterCFN )
{
// good input
break ;
}
else
{
std::cout << "Enter a digit: ";
// clear stream flags set due to bad input
std::cin.clear();
// get rid of the bad input.
// ignore the rest of the line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}

Switch-statement inside a while-loop which loop infinitely

Here is my code:
int main()
{
int nothing;
string name;
int classnum;
bool classchosen;
string classname;
cout << "Welcome adventurer, your journey is about to begin.\n\n";
cout << "Firstly, what's your name? ";
cin >> name;
classchosen = false;
while (classchosen == false)
{
cout << "\n\nNow, " << name << ", choose your class entering its number.\n\n";
cout << "1- Warrior\n" << "2- Mage\n" << "3- Paladin\n" << "4- Monk\n\n";
cout << "Class number: ";
cin >> classnum;
switch(classnum){
case 1:
classname = "Warrior";
classchosen = true;
break;
case 2:
classname = "Mage";
classchosen = true;
break;
case 3:
classname = "Paladin";
classchosen = true;
break;
case 4:
classname = "Monk";
classchosen = true;
break;
default:
cout << "\nWrong choice, you have to enter a number between 1 and 4.\n" << endl;
break;
}
}
cout << "\nSo you are a " << classname << " ? Well, tell me something more about you...\n";
cin >> nothing;
return 0;
}
Now, when I run it and input a string (for example "fjdfhdk") when it asks about the class number, the program loops infinitely instead of going in the default statement, writing again the question and letting me choose another class. Why?
Try something like this:
#include <sstream>
#include <string>
using namespace std;
int getInt(const int defaultValue = -1){
std::string input;
cin >> input;
stringstream stream(input);
int result = defaultValue;
if(stream >> result) return result;
else return defaultValue;
}
//..in main
cout << "Class number: ";
int classNum = getInt();
switch(classNum){ .... }
The reason why it fails in your case is because cin is trying to read a bunch of chars into a int variable. You can either read it as a string and convert as necessary, or you can check the cin state explicitly when reading into a int variable by checking if any of the fail bits are set. The fail bits would be set if for example you try to read bunch of chars into an int.
Because you're reading into an int, and the read fails. This
has two effects:
your use of classnum afterwards is undefined behavior, and
the stream has memorized the error condition, so you can
check it later.
As long as the error condition is not cleared, all further
operations on the stream are no-ops. The simplest changes in
your program to make this work would be:
std::cin >> classnum;
if ( !std::cin ) {
classnum = 0;
std::cin.clear();
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
}
switch ( classnum ) // ...
In case of an error, this sets classnum to a known value,
clears the error state, and skips all input up to the next
newline. (Otherwise, you'll just fail again, because the
characters which triggered the error are still there.)
Consider, however, using a separate function to extract the int,
and using getline, as per user814628's suggestion. The above
is more to explain to you what is happening, and why your see
the symptoms you see. user814628's suggestion is far better
software engineering.

C++ cin only accept numeric values

I've written this piece of code that allows the user to choose input either the value 1 or 2. This is working perfectly fine aside from one minor issue:
If the user inputs something like "1asdaosd" the input is recognized only as 1.
I've tried using the isdigit function but I still didn't manage to make this work.
bool validInput;
do
{
cout << "Choose the game type: ";
cin >> gametype;
validInput = true;
if (cin.fail())
{
validInput = false;
cin.clear();
cin.ignore(std::numeric_limits<int>::max(), '\n');
}
if (gametype<1 || gametype>2) {
validInput = false;
}
} while (!validInput);
The expected behaviour should be:
Anything other than "1" or "2" shouldn't be considered a validInput and therefore repeating the cycle. What happens is that "1asdasd" or "2aods" is considered a validInput but I want it to fail.
Below is a method based on stuff I read in one of the early chapters of Stroustrup's Programming: Principles and Practice Using C++ and an answer provided by Duoas at cplusplus.com. It defines a function, get_int_between(), that allows you to do something like this:
int my_variable;
get_int_between(my_variable, min, max, prompt, error_msg);
Which would prompt, validate, and store into my_variable.
Just for fun, I've also included a function, get_int(my_variable, prompt, error_msg), that does the same thing but allows an integer of any value.
#include <iostream>
#include <sstream> // stringstream
void get_int(int& d, std::string prompt, std::string fail);
void get_int_between(int& d, int min, int max, std::string prompt, std::string fail);
int main()
{
int my_number = 1; // initialize my_number
get_int(my_number, "Please enter an integer: ", "Sorry, that's not an integer.\n");
//Do something, e.g.
std::cout << "You entered: " << my_number << "\n";
get_int_between(my_number, 1, 2, "Choose the game type (1 or 2): ", "Sorry, that's not an integer.\n");
//Do something, e.g.:
std::cout << "Let's play Game " << my_number << "!\n";
return 0;
}
void get_int(int& d, std::string prompt, std::string fail)
{
while(1) {
std::cout << prompt;
std::string str;
std::cin >> str;
std::istringstream ss(str);
int val1;
ss >> val1;
if(!ss.eof()) {
std::cout << fail;
continue;
} else {
d = val1;
break;
}
}
}
void get_int_between(int& d, int min, int max, std::string prompt, std::string fail)
{
while(1) {
get_int(d, prompt, fail);
if(d > max || d < min) {
std::cout << "Sorry, your choice is out of range.\n";
continue;
}
break;
}
}
If you want to use strings use getline.
#include <iostream> // std::cin, std::cout
int main ()
{
char name[256], title[256];
std::cout << "Please, enter your name: ";
std::cin.getline (name,256);
std::cout << "Please, enter your favourite movie: ";
std::cin.getline (title,256);
std::cout << name << "'s favourite movie is " << title;
return 0;
}
if you make gametype as an int it will only accept 1 or 2 (of course you have to prevent other numbers to be accepted).
It's because gametype is an integer, so it's trying to read as much as would be valid for an integer. 1asdaosd is not a valid integer so it stops at the 1. If you want to read that thing in completely you'll have to make gametype a string for example, but then you won't be able to compare it to integers as you already do.
You can read it as a string if you want, and if you want to handle the case of strings and ints both, then you can use something like stoi to attempt to convert the string to an integer. Then catch the std::invalid_argument exception so you can know if the string can be converted to an integer. If it can't, then you know to keep it as a string.
It reads an int as far the input can be construed as such. Then stops. If you read into a string variable it will get it all.
Read data into a string variable.
Check that data is a valid integer.
Convert string to integer.
Tedious but it's the only way to do it
I'm guessing you want one input value on each line. You need to read this as string and then check if you got more than you asked for. If you need it as an integer you can convert the read string later.
I'm also assuming you only need to read single digit integers. More digits need the string to integer conversion in the loop and some more checks.
string gametype;
do
{
cout << "Choose the game type: ";
// read one word as string, no conversion, so will not fail (may hit eof though)
cin >> gametype;
// ignore rest of line (assuming you want next valid input on next line)
cin.ignore(std::numeric_limits<int>::max(), '\n');
}
while ( gametype.size() != 1 || gametype.at(0) < '1' || gametype.at(0) > '2') );
// char to int conversion (single digit only)
int gametypeint = gametype.at(0) - '0';
// other way to convert string to int
istringstream iss(gametype);
iss >> gametypeint;
// yet another way (C++11)
gametypeint = stio(gametype);