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;
}
Related
This question already has answers here:
How do I pass a cin'd c style string to a function?
(2 answers)
Closed last year.
Here is my code I am expecting the output but I am not getting .It stop after taking the input
I am expecting the output if i give name Harsh
Your name is Harsh
#include <iostream>
#include <cstring>
using namespace std;
int main() {
cout << "Enter your name" << endl;
char *s;
cin >> s;
cout << "Your name is " << s;
return 0;
}
I have also tried with cin.getline(s,100);but still it is not working.
So I request to you to solve the problem and give me solution.
Your code has undefined behavior because you are not allocating any memory for s to point at. s is an uninitialized pointer.
Try this instead:
#include <iostream>
using namespace std;
int main(){
cout << "Enter your name" << endl;
char s[100];
cin >> s; // or: cin.getline(s,100);
cout << "Your name is " << s;
return 0;
}
Alternatively, you should use std::string instead, eg:
#include <iostream>
#include <string>
using namespace std;
int main(){
cout << "Enter your name" << endl;
string s;
cin >> s; // or: getline(cin,s);
cout << "Your name is " << s;
return 0;
}
s in your code is unallocated.
Since it is C++ we're talking about, you probably don't want to use pointers and memory allocation, and use std::string instead.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
cout << "Enter your name" << endl;
string s; // Instead of dealing with char* allocation and memory issues.
cin >> s;
cout << "Your name is " << s;
return 0;
}
you have done it correctly but the problem with output is because of the memory allocation.
You have to allocate memory and try to avoid the concept of a pointer in that. Instead
Use string s;
or
char s[50];
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.
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.
I want to be able to loop this file opening and closing to continually search for names.
The first time is no problem and output is what is expected then, when choosing y for yes, an output loop occurs.
Any ideas as to why this would happen? The logic seems more than correct.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string boys, girls, name;
int rank;
char end = 'n';
while (end != 'y' || end != 'Y')
{
cout << "Enter a name to search";
cin >> name;
ifstream input;
input.open("Names2016");
if (input.fail())
cout << "Failed to open file.\n";
while (!input.eof())
{
input >> rank >> boys >> girls;
if (boys == name)
cout << name << " ranks " << rank << " among boys.\n";
if (girls == name)
cout << name << " ranks " << rank << " among girls.\n";
}
input.close();
cout << "Would you like to search another name?\n"
<< "Enter Y for yes or N for no.\n";
cin >> end;
}
return 0;
}
There are a some of things you can do to make this code better,
The first is to use ifstreams and do file input/output the proper idiomatic way in a loop, don't use .eof() to check for end of file in a loop condition (the answer linked in the comments is a good place to start if you want to know why),
The second thing you want to check for validity of the file with a simple if (!file) its much cleaner IMO.
The third thing is, when you have a local file handle like you do in your code, then you can just let it go out of scope and let the destructor cleanup the file and close() it, it's the C++ RAII way of doing things (notice that I have removed the open() method to the constructor call (which does the same thing)
Use cerr instead of cout to report errors
Use char instead of int to represent characters
Not a big change, but using std::toupper like advised in the other answer's comments is a good readable way to check for uppercase and lowercase values at the same time
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string boys, girls, name;
int rank;
char end = 'n';
while (std::toupper(end) == 'Y')
{
cout << "Enter a name to search";
cin >> name;
ifstream input{"Names2016"};
// change here
if (!input) {
cerr << "Failed to open file.\n";
}
while (input >> rank >> boys >> girls)
{
if (boys == name)
cout << name << " ranks " << rank << " among boys.\n";
if (girls == name)
cout << name << " ranks " << rank << " among girls.\n";
}
// change below, just let the file handle go out of scope and close
// input.close();
cout << "Would you like to search another name?\n"
<< "Enter Y for yes or N for no.\n";
cin >> end;
}
return 0;
}
But you can do better on the I/O if your file isn't guaranteed to change over different iterations (in which case you probably need to make sure that there is no race anyway, so I am assuming the file does not change much). Read in the file once and save that information to be used later
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <unordered_map>
#include <vector>
using namespace std;
int main()
{
string boys_name, girls_name, name;
int rank;
char end = 'n';
ifstream input{"Names2016"};
if (!input) {
cerr << "Failed to open file" << endl;
}
// preprocess the information and store it in a map
// making a map from string to vector because it is unclear whether
// there is a 1-1 mapping from the name to the rank for each name
unordered_map<string, vector<int>> boys;
unordered_map<string, vector<int>> girls;
while (input >> rank >> boys_name >> girls_name) {
boys[boys_name].push_back(rank);
girls[girls_name].push_back(rank);
}
while (std::toupper(end) == 'Y')
{
cout << "Enter a name to search";
cin >> name;
// use the map to do the lookup, much faster than reading
// the entire file over and over again
}
return 0;
}
First of all, what is this supposed to mean int end = 'n'; Are you assigning an integer with a character value?!
And why are you opening the same file inside the loop. You should probably open it only once at the beginning of the program.
And the eof doesn't have what to check for, because you have to read from a file to reach its end.
I have to create a simple code that is supposed to create a .txt file as an output, containing a list fo notations with this format. (time ; topic ; comment)
the code has to run a loop using a struct function showed below:
struct annotation_t {
string topic;
string comment;
time_t stamp;
};
so the user can input the notations as many times he wants till he decides to go out. This is what I did so far.
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
struct annotation_t {
string topic;
string comment;
time_t stamp;
};
int main()
{
int q = 0;
std::vector<annotation_t> obj;
do
{
annotation_t temp = {};
cout<< "input your topic: ";
cin >> temp.topic ;
cout<< "input yourfeedback: ";
cin >> temp.comment ;
cout<< "input your time stamp: ";
cin >> temp.stamp ;
cout<< "exit?";
cin >> q;
obj.push_back(temp);
} while (q != 0);
ofstream myfile("annotation.txt");
char time[1000];
for(int i = 0;i<50;i++)
{
struct annotation_t obj[i];
myfile<<obj[i].stamp <<" "; // write in file
myfile<<obj[i].topic <<" ";// write in file
myfile<<obj[i].comment; // write in file
myfile<<"\n";
}
cout<<"\nFile Created with Data with name annotation.txt \n";
myfile.close();
system("Pause");
}
I have a problem when it come to exit. if I input any value( even 0) I get a segmentation fault so i am not able to quit the loop and save my file in the txt, or re run it if I want to input more.. Let me know your thoughts.thanks
int i=0;
struct annotation_t obj[i];
You're making an array of annotation_t objects of 0 size
cin >> obj[i].topic ;
Then attempting to access the first element.
Consider using std::vector instead, which will allow you to dynamically change the size of your container to allow the user to input as many as they'd like:
// Empty container
std::vector<annotation_t> obj;
do
{
// Create temporary
annotation_t temp = {};
// Accept input:
cin >> temp.topic;
...
// Add to container:
obj.push_back(temp);
}
In your beneath for loop, you are doing the same thing as above
for(int i = 0;i<50;i++)
{
struct annotation_t obj[i];
Plus, you are creating a new container. You probably intend to use the container from above, which will change your loop into:
// Store the contents of the now populated obj from above
for (auto& a : obj)
{
myfile << a.stamp << " ";
myfile << a.topic << " ";
myfile << a.comment << std::endl;
}
You have problem with declaration 'obj' object.
This is wrong :
struct annotation_t obj[i];
Try this instead :
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
#include <cstdlib>
using namespace std;
struct annotation_t {
string topic;
string comment;
time_t stamp;
};
int main()
{
int q = 0;
struct annotation_t obj[1000]; //msf
int i=0; //msf
do
{
cout<< "input your topic";
cin >> obj[i].topic ;
cout<< "input yourfeedback";
cin >> obj[i].comment ;
cout<< "input your time stamp";
cin >> obj[i].stamp ;
cout<< "exit?";
cin >> q ;
i++; //msf
} while (q != 0);
ofstream myfile("annotation.txt");
int count=i; //msf
for(i = 0;i<count;i++) //msf
{
myfile<<obj[i].stamp <<" "; // write in file
myfile<<obj[i].topic <<" ";// write in file
myfile<<obj[i].comment; // write in file
myfile<<"\n";
}
cout<<"\nFile Created with Data with name annotation.txt \n";
myfile.close();
system("Pause");
}
I changed your code in many positions that I commented with '//msf'.
I don't have C++ compiler in hand then I hope it will be compiled without errors.