Why are my if statements not working with strings in c++? - c++

I'm a newbie with c++, and I tried googling a solution but every one I came across was so different from the issue I was facing so I couldn't figure it out. The problem I'm having is my "if" statements are completely ignored when I run the .exe from powershell.
https://pastebin.com/aE6MiQig
#include <iostream>
#include <string>
using namespace std;
int main()
{
string q;
string w;
string Bob;
string Emily;
{
cout << "Who is this? ";
cin >> q;
if (q == Bob)
{
cout << "Hey there bro. ";
}
if (q == Emily)
{
cout << "Hi friend :) ";
}
else
{
cout << "Oh hey " << q << ", how are you? ";
}
cin >> w;
cout << "Hey, that's " << w;
}
return 0;
}
When I input my name as "Bob" I should be seeing the message from the if statement "Hey there bro." but I am instead seeing the else statement, "Oh hey Bob, how are you?". Same goes when I input Emily. Only seeing the else statement.
I'm not getting any errors (running this in visual studio) so where am I messing this up?

Why not just compare directly to strings?
#include <iostream>
#include <string>
int main()
{
std::string q;
std::string w;
std::cout << "Who is this? ";
std::cin >> q;
if (q == "Bob") // note the quotation marks around Bob
{
std::cout << "Hey there bro. " << std::endl;
}
else if (q == "Emily") // note the quotation marks around Emily
{
std::cout << "Hi friend :) " << std::endl;
}
else
{
std::cout << "Oh hey " << q << ", how are you? ";
std::cin >> w;
std::cout << "Hey, that's " << w << std::endl;
}
return 0;
}
Also, you should avoid using namespace std because it leads to namespace pollution. Instead, you can just put std:: in front of string, cin, cout, and endl as I've done above, or include a using statement for each of those specifically, like this:
using std::string;
using std::cin;
using std::cout;
using std::endl;

std::string comes with its own operator==, comparing the string's contents.
string Bob;
string Emily;
Well, now you have created two strings, both using the default constructor, and so both are empty strings (i. e. they both would compare equal to "").
You need to assign them a value:
string Bob("Emily");
string Emily("Bob");
I deliberately assigned them inverse! Try this piece of code and you'll discover yourself that it is the content that is relevant for comparison, not the variable's name...

You obtain the value for string q from the user and compare it to string Emily or string Bob , neither of which have any values assigned.
The problem I'm having is my "if" statements are completely ignored when I run the .exe from powershell.
Your if statements are not being ignored instead you're comparing string q to "".
You can give string Bob and string Emily initial values:
#include <iostream>
#include <string>
int main()
{
std::string Bob = "Bob";
std::string Emily = "Emily";
std::string q;
}
This way you have something to compare the values you're getting from cin to:
#include <iostream>
#include <string>
int main()
{
std::string Bob = "Bob";
std::string Emily = "Emily";
std::string q;
std::cout<<"What is your name? ";
std::cin>>q; //Obtain value from cin
if(q == Emily){}//If q is Emily, then do something
}
You can read more about default variable values here and here.

Related

New int by user input

I have a problem. I want to create an integer by user input. For example:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0;
char newVar;
string newVarName;
cout << "New Variable? (y/n)" << endl;
cin >> newVar;
if (newVar == 'y') {
/* newVarName declares new int with the name
of the user input (newVarName = test --> int test)*/
} else {
break;
}
return 0;
}
How can I do this?
As #Fantastic Mr Fox mentioned :
int name_dependant_on_user_input = value_from_user
This is impossible in c++, because the variable name, is a compile
time thing. The user input happens at runtime, which is after
compilation has completed. Something you could do, is map a string
input to your user input, for eg.
Some other error: String should be string or std::string. And using break; while not within loop or switch statements will return an error. If you want to escape immidiately, you could use exit(0);
Otherwise, as #Eljay mentioned above, a map<string, int> can be used to store both the name and value of your variable:
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
char newVar;
string newVarName;
map<string, int> varName;
cout << "New Variable? (y/n) : ";
cin >> newVar;
if (newVar == 'y') {
cout << "Name : "; cin >> newVarName;
cout << "Int : "; cin >> varName[newVarName];
} else {
exit(0);
}
//testing
cout << "Test : " << newVarName << " = " << varName[newVarName];
return 0;
}
Result:
New Variable? (y/n) : y
Name : var
Int : 5
Test : var = 5
Also, see why using namespace std; is considered a bad practice.
More info:
std::map : https://en.cppreference.com/w/cpp/container/map
std::string: https://en.cppreference.com/w/cpp/string/basic_string
In c++, you need to be aware of the common concepts of compile time and run time. So in your example:
// newVarName declares new int with the name of the user input
If you mean something like this:
int name_dependant_on_user_input = value_from_user
This is impossible in c++, because the variable name, is a compile time thing. The user input happens at runtime, which is after compilation has completed. Something you could do, is map a string input to your user input, for eg.
std::unordered_map<std::string, int> user_vars;
std::string variable_name;
int variable_value;
cin >> variable_name;
cin >> variable_value;
user_vars[variable_name] = variable_value;
...
for (const auto& value_pair : user_Vars) {
std::cout << "User value for " << value_pair.first << " is " << value_pair.second;
}

Is it possible to put multiple names in one string?

I just started learning C++ and I'm currently following a tutorial on YouTube.
I thought it was fun to make a very simple 'access' program. If I type in my name it says, "Welcome!" If I type in another name it says, "access denied". It worked perfectly fine, but then I wanted the program to say "Welcome!" to two different names. So, I wanted to add a second name in the string, but I couldn't figure out how to do that. I googled a lot but I couldn't find anything. In the end, I came to string name = ("Joe", "Sean");, but here, it was only valid for Sean. I just can't figure out how to put multiple names in one string and make them both work. I hope you can help me, here is my code:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
string name = ("Joe", "Sean");
string input;
cout << "What is your name?\nMy name is: ";
cin >> input;
if(input == name){
cout << "Welcome, "<< input <<"! ";
} else {
cout << "Access denied";
}
return 0;
}
This is a way to do it using a vector of strings, so you can adapt easily with more names :
#include <iostream>
#include <vector>
using namespace std;
void printMessage(string message)
{
std::cout << message << std::endl;
}
int main()
{
vector<string> names{"Joe", "Sean", "Paul"};
string input;
cout << "What is your name? " << endl;
cin >> input;
for (string name : names)
{
if (name == input)
{
printMessage("Welcome!");
return 0;
}
}
printMessage("Access Denied!");
return 0;
}
The problem is in the string variable "name". You need an array of strings, not a single string.
This is an example implementation:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
string names[] = {"Joe", "Sean"};
string input;
cout << "What is your name?\nMy name is: ";
cin >> input;
for (int i = 0; i < end(names) - begin(names); i++) {
if(input == names[i]){
cout << "Welcome, "<< input <<"! " << endl;
return 0;
}
}
cout << "Access denied" << endl;
return 0;
}
You encountered some quirky features of C++ in the approach you are using to initialize your string variable:
string s1 = ("Joe"); // creates a string "Joe"
string s2 = ("Joe", "Sean"); // creates 2 strings, "Joe" and "Sean", and the variable s2 stores only the latter!
For more details on the different methods for initializing variables there has been an interesting discussion in this previous question.

Issue printing .txt file in program C++

I have a program that takes a text file and list the words and how many times they are used. It works but I can't figure out how to print out the text file. Above the sorted words and how many times they appear, I want to display the text from the file. How would I do that? I tried several things but it either does nothing or screws up the rest of the code saying there are 0 unique words. And lastly how would print out the results so they are more ... table -ish...
/*
Something like this:
Word: [equal spaces] Count:
ask [equal spaces] 5
anger [equal spaces] 3
*/
Thank you for any assistance you can provide me.
#include <iterator>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <cctype>
using namespace std;
string getNextToken(istream &in) {
char c;
string ans="";
c=in.get();
while(!isalpha(c) && !in.eof())//cleaning non letter charachters
{
c=in.get();
}
while(isalpha(c))
{
ans.push_back(tolower(c));
c=in.get();
}
return ans;
}
string ask(string msg) {
string ans;
cout << msg;
getline(cin, ans);
return ans;
}
int main() {
map<string,int> words;
ifstream fin( ask("Enter file name: ").c_str() ); //open an input stream
if( fin.fail() ) {
cerr << "An error occurred trying to open a stream to the file!\n";
return 1;
}
string s;
string empty ="";
while((s=getNextToken(fin))!=empty )
++words[s];
while(fin.good())
cout << (char)fin.get(); // I am not sure where to put this. Or if it is correct
cout << "" << endl;
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "----------------------------------------------------------------" << endl;
cout << " " << endl;
for(map<string,int>::iterator iter = words.begin(); iter!=words.end(); ++iter)
cout<<iter->first<<' '<<iter->second<<endl;
return 0;
}
I would just use a simple for loop like this:
for (int x = 0; x < words.size(); x++){
cout >> words[x] << endl
}
And then modify from there to get your desired format.
I did notice though, that you are not returning a value for main in all paths of the above code, which should give a compile time error, but did not when I compiled it, for some reason. I would remind you that you need to have a return value for main. Unless I am misunderstanding your question. I could not run this program without creating a sample file, and so could not test it without extra work. But the program did compile. I did not expect to, because of the missing return statement. If you can make this reproduce your error without me having to create a sample file of words, ei insert the list of words into the code and minimally reproduce the error, I would be able to help you better. As it is, I hope that I helped you.
Something like this should make it:
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <string>
int main( int argc, char* argv[] )
{
std::string file;
std::cout << "Enter file name: ";
std::cin >> file;
std::fstream in( file.c_str() );
if ( in.good() )
{
std::unordered_map<std::string, int> words;
std::string word;
//Use this to separate your words it could be '\n' or anything else
char cSeparator = ' ';
while ( in >> word )
{
//Print the word
std::cout << word << cSeparator;
++words[word];
}
std::cout << std::endl;
//Headers Word and Count separated by 2 tabs
std::cout << "Word:\t\tCount:" << std::endl;
for ( auto& w : words )
std::cout << w.first << "\t\t" << w.second << std::endl;
}
in.close();
return EXIT_SUCCESS;
}
However this is assuming that the text file only contains the words, if you have other kind of stuff there, you should be able to filter it as you want.

Password function and arrays

I'm writing a simple password program, but the else if statement always applies, even if the password is put in correctly. This works fine if I use a single char instead of an array, and change "hotdog" to 'h', and I think it might have something to do with unseen characters, like a space or return. I was sure cin.ignore() took care of return/enter.
Sorry, I'm fairly new to programming.
#include <iostream>
int main()
{
std::cout << "What is the password?\n" << std::endl;
char password[20] = "NULL";
std::cin >> password;
std::cin.ignore();
std::cout << password << " is your entry?\n";
if (password == "hotdog")
{
std::cout << "Correct!";
}
else if (password != "hotdog")
{
std::cout << "Incorrect!";
}
else
{
}
std::cin.get();
}
Firstly, change char password[20] to string password. This prevents a buffer overflow if they type in more than 20, and it enables you to use == for string comparison.
The code std::cin.ignore() ignores a single character. You want to actually ignore the entire remainder of the line. There is no way to ignore "everything else typed so far" because there may have been characters typed which are still buffered. In practice, it works well to treat input as a series of lines.
The most accurate way to ignore the rest of the line is to ignore all characters up to and including '\n', which appears in the input stream at the end of the line (by definition).
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
which may require #include <limits>. Another way is to read a string and discard it:
std::string t;
std::getline( std::cin, t );
NB. Check your understand of if...else . Once you have if ( condition ), then the next else will already get everything that was not in that condition. It's pointless to actually write else if ( !condition ); and your final else { block can never be entered, because the previous two conditions were exhaustive.
The problem is with how you are using the if-else statement. Try this code out:
#include <iostream>
int main()
{
std::cout << "What is the password?\n" << std::endl;
char password[20] = "NULL";
std::cin >> password;
std::cin.ignore();
std::cout << password << " is your entry?\n";
if (stricmp("hotdog", password) == 0)
{
std::cout << "Correct!";
}
else
{
std::cout << "Incorrect!";
}
std::cin.get();
}
When I take your code and compile it, even the term hotdog does not work properly, I obtain the following:
What is the password?
hotdog
hotdog is your entry?
Incorrect!
As suggested above, a string is a better method and works as intended based on your requirements. Here is sample replacement code that works as intended (with this code spaces are allowed, with the other answers, spaces are not, it all depends what is intended):
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char ** argv)
{
cout << "What is the password?\n" << endl;
string password = "NULL";
getline(cin, password);
cout << password.c_str() << " is your entry?\n";
if (password == "hotdog")
{
cout << "Correct!";
}
else if (password != "hotdog")
{
cout << "Incorrect!";
}
else
{
// Added from original; however, this should never occur
cout << "Else?";
}
system("pause");
return 0;
}
Output of Replacement Code
What is the password?
hotdog
hotdog is your entry?
Correct!
You had to use strcmp() function to compare strings properly in c++,so I added the cstring library:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main(){
string password;
cin >> password;
cout << password << " is your entry?\n";
char hd [7] = "hotdog";
if (strcmp(password.c_str(),hd) == 0){
cout << "Correct!\n";
}
else if (strcmp(password.c_str(),hd) != 0){
cout << "Incorrect!\n";
}
else{
cin.get();
}
}

How do I get the this program to read what the person type as a string and see if the strings are equal?

I need help ... How do I get the this program to read what the person type as a string and see if the strings are equal?
#include <iostream>
using namespace std;
int main()
{
char name;
cout << "Type my name is:";
cin >> name;
if
name ==char('Mike') //this is where i think the problem is...
cout << "congrats";
else
cout << "Try again";
}
#include <iostream>
int main()
{
std::string name;
std::cout << "Type my name is:";
std::cin >> name;
if (name == "Mike") // Compare directly to the string "Mike"...
std::cout << "congrats";
else
std::cout << "Try again";
}
I think it is always better habit to use std:: instead of using namespace std.
Have you tried using std::string in c++?
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Type my name is:";
cin >> name;
if (name == "Mike"))
cout << "congrats";
else
cout << "Try again";
}
Your problem is that char is a character variable, not a character array. If you want to create a 'c-string' (collection of characters), use char name[20]. To create a string object, use string name. Don't forget to #include <string>. Here's a brief tutorial for strings:
http://www.cplusplus.com/doc/tutorial/ntcs/
If you want to use c-strings, you have to use strcmp(name,"Mike") to compare two strings. It returns true if two strings are DIFFERENT, so be careful.
#include <iostream>
using namespace std;
int main()
{
char name[20];
cout << "Type my name is:";
cin >> name;
if (!strcmp(name,"Mike")) //C string equality tester
cout << "congrats";
else
cout << "Try again";
}
Strings are easier to use because you can just use the equality operator ==.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Type my name is:";
cin >> name;
if (name == "Mike") //Tests for equality using strings
cout << "congrats";
else
cout << "Try again";
}
Also, watch your quotation marks. Single quotes ('a') are for characters, double quotes ("Mike") are for character arrays (words, sentences, etc.)
char is a single character, replace all your char with std::string and add #include <string> to the beginning of you code. std::string will save arbitrary length strings.
if is followed by braces: if(...). In your case if(name == char('Mike')) or with the advice from above if(name == std::string('Mike')).
In C and C++ the two quotes ' and " are different. You use ' for single characters and " for strings. So it needs to be if(name == std::string("Mike")).
You may also write if(name == "Mike").
Also you should make brackets to increase readability and avoid errors. After if(...) you would usually use {} to encapsulate the instructions to be executed if the condition in if(...) is met. Your case is special, because the brackets may be left out for single instructions.
if(...)
{
...
}
else
{
...
}
int main()
{
string name;
string myname("Mike");
cout << "Type my name is:";
cin >> name;
if(name ==myname) //this is where i think the problem is...
{
cout << "congrats";
}
else
cout << "Try again";
}
This should do it. But I'm sure you don't want to hard-code "Mike" ONLY. A good improvement would be to get names from a file and then compare. Also keep in mind that string == operator is case sensitive so "Mike" != "mike"