Passing a string by reference in c++ - c++

I am working on a code for my c++ class. The assignment is to read the names from 2 different txt files(already in my directory) and find if the string/name that the user searched for matches any of the names already in the files. My code seems good to me, but I am getting an error in my function prototype saying "string was not declared in this scope." Any solutions? My code is here as follows:
#include <fstream>
#include <string>
#include <vector>
void boysfunc(string&, string&);
void girlsfunc(string&, string&);
using namespace std;
int main()
{
vector<string> boysnames;
vector<string> girlsnames;
string boysname, girlsname;
ofstream outputFile;
cout << "Enter a boy's name, or N if you do not want to
enter a name: ";
cin >> boysname;
cout << "Enter a girl's name, or N if you do not want to
enter a name: ";
cin >> girlsname;
if (boysname != "N")
{
boysfunc(boysname, boysnames);
}
if (girlsname != "N")
{
girlsfunc(girlsname, girlsnames);
}
}
void boysfunc(string &boysname, string &boysnames)
{
outputFile.open("BoysNames.txt");
while(outputFile >> boysnames)
{
/*Declare local variable count to use as a counter*/
int count = 0;
if (boysnames(count) == boysname)
{
outputFile.close();
cout << "The name " << boysname << " is very
popular among boys.";
return;
}
else
{
count++;
}
}
}
void girlsfunc(string &girlsname, string &girlsnames)
{
outputFile.open("GirlsNames.txt");
while(outputFile >> girlsnames)
{
/*Declare local variable count to use as a counter*/
int count = 0;
if(girlsnames(count) == girlsname)
{
outputFile.close();
cout << "The name " << boysname << " is very
popular among girls.";
return;
}
else
{
count++;
}
}
}

There are two major errors that you need to fix here.
using namespace std; must be written before the use of strings if you wish to omit std:: before writing string. Otherwise, you can write std::string& in the function declarations.
boysfunc() and girlsfunc() are taking vector<string>& as the second argument, whereas you incorrectly mentioned string& in the functions' declaration and definition. Fix that.

In this snippet
string s = "hello";
using namespace std;
the type string is not known to the compiler. That's what using namespace std; does. It basically turns string into std::string.
You could swap the 2 lines above, and it will work, but I highly recommend just saying std::string explicitly everywhere. I'm sure your IDE will let you do this easily.

Related

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.

Checking user input if is equal to a array element

I have a string array with multiple names.
I would like to check using an if statement if the user input is equal to any of the names.
For example:
names[5] = {'david','rares','tudor','john','jay'}
cin>>name;
And now i would like to check if name is equal to any of the elements in the array.
Very Bad Example:
if(name == names)
{
cout<<"you can use this name. Name: "<<name;
}
As pointed out by user4581301, 'david' isn't a string but a multibyte character (and most probably not a valid one either). If you want to keep a set of names and check if some name exists in it, you could use a std::set or std::unordered_set instead of an array. Example:
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> names = {"david", "rares", "tudor", "john", "jay"};
std::string name;
std::cin >> name;
if(names.count(name)) // or names.contains(name) in C++20
std::cout << "found\n";
else
std::cout << "not found\n";
}
I would suggest using a vector to store the names so you know your size. If you must use a static array, make sure to save the current size and update it whenever removing/adding names.
Somebody may have a more efficient solution, but you can linearly search through the array using a for loop.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
string names[5] = {"david","rares","tudor","john","jay"};
cout << "Enter name: ";
cin >> name;
for (int i = 0; i < 5; i++)
{
if(names[i] == name)
{
cout << name << " was found in the array." << endl;
return 0;
}
}
cout << name << " wasn't found in the array." << endl;
return 0;
}
This solution won't work for case sensitive names (David and david are considered two seperate names).
You can do something like this:
#include <iostream>
#include <algorithm>
int main()
{
const char * v [] = { "david", "rares", "tudor", "john", "jay" };
std::string name;
std::cin >> name;
auto result = std::find (std::begin (v), std::end (v), name);
if (result != std::end (v))
std::cout << name << " is valid\n";
}
although please note that most people would use std::vector <std::string> to hold the list of strings.
Live demo

Why are my if statements not working with strings in 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.

Keep getting "member reference base type 'string [1000]' is not a structure or union" error and dont know how to fix it?

This program reads an SSN from the user and checks if it matches an SSN in a text file provided. Tried switching the array to a vector and it didnt work. Tried putting the array in the structure function and using info:: but nothing seems to work. I know this is pretty basic but I cant get it, thanks.
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[]){
struct info{
string SSN;
string firstName;
string lastName;
};
string list[1000];
string userSSN;
char x;
fstream input(argv[1]);
int i = 0;
while(!input.eof()){
input >> list.x[i] >> list.SSN[i] >> list.firstName[i] >> list.lastName[i];
i++;
}
input.close();
cout << "Input a SSN:" << endl;
cin >> userSSN >> endl;
for(int k = 0; k < i; k++){
if(userSSN.compare(list.SSN[k]) == 0){
cout << "Found at location " << k << endl;
}
}
}
list is just an array of 1000 std::strings. It looks like you need it to be of type info. Even that won't solve your problems as info has no member named x. After that, to access a member of info in an array would be like
list[i].SSN
not
list.SSN[i]
There are so many things wrong with this code that I don't know where to start. Let's see:
Using using namespace std; is almost always a bad idea, and if you have an identifier list, then it's even worse because it conflicts with std::list.
Using std::string without #include <string> is not guaranteed to work. It may work if you include some other standard header, but don't rely on it.
Your variable x is unused.
string list[1000]; should probably be info list[1000];.
list.SSN[i] et al should probably be changed to list[i].SSN.
list.x[i] does not make sense at all and can probably be removed. (Or you meant to read into the otherwise unused x to skip parts of the file.)
You cannot read from std::cin into std::endl. Remove std::endl from that line.
Using std::string's compare function is pretty strange here, just use ==.
The issues in your code were already pointed out in other's answers. I'll show you a "working" example:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using std::string;
using std::vector;
using std::cout;
using std::cin;
struct info {
char x; // You were reading that from the file so I added it
string SSN;
string firstName;
string lastName;
friend std::istream &operator>>( std::istream &is, info &i ) {
// maybe you should check data input somehow...
is >> i.x >> i.SSN >> i.firstName >> i.lastName;
return is;
}
};
int main(int argc, char* argv[]) {
// check if a file name has been passed as a parameter
string file_name;
if ( argc < 2 ) {
cout << "Please, enter the input file name:\n";
cin >> file_name;
}
else
file_name = argv[1];
std::ifstream input(file_name);
if ( !input ) {
std::cerr << "Error. Unable to open file: " << file_name << '\n';
exit(-1);
}
// Just use a vector to store all the structs
vector<info> my_list;
info temp_info;
while( input >> temp_info ) {
my_list.push_back(temp_info);
}
input.close();
cout << "Input a SSN: ";
string userSSN;
cin >> userSSN;
// That's not cheap. You may want to change the container or sort it
for ( int k = 0; k < my_list.size(); k++ ) {
if ( userSSN == my_list[k].SSN ) {
cout << "Found at location " << k << '\n';
}
}
return 0;
}

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"