If conditioning and String [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am very new at C++ and deeply appreciate your help!
I am trying to make a 'If' condition for a string, that is, for example:
#include <iostream>
using namespace std;
int main()
{
string message = "HELP";
int password;
cout<<"Please enter password";
cin<<password;
if (password = message);
}
else {
cout<<"Please try again...";
}
cin.ignor()
}
However Int is not for strings I believe and of course on Code::Blocks it posts the error that it doesn't function in such case. So basicaly just when someone on C++ saves a variable for int X; X = 3; for example, how can we do that with letters so that I can pop if condition message boxes!
Again thanks for helping! =D

= is assignment. == is comparision. Also, don't put semicolon after the if statement.

#include <iostream>
using namespace std;
int main()
{
string message = "HELP";
string password;
cout << "Please enter password";
cin >> password;
if (password != message)
{
cout << "Please try again...";
}
return 0;
}
Should work a little better.

This is the first problem:
int password;
The data type of password should be std::string as well, because message is std::string (which contains the valid password).
So the first fix is this:
std::string password;
Second problem is that you're using '=' in if. Use '==' (equality operator), not '=' (assignment operator).

First off, if you want the password to be anything, not just a number, use std::string.
To compare two values, use == NOT =.
#include <string>
#include <iostream>
int main()
{
std::string s1("First string");
std::string s2("Second string");
if(s1 != s2) {
std::cout << "Strings don't match!" << std::endl;
}
}
In your code, you also didn't properly close all blocks and misspelled cin.ignore().

What you probably want to do is:
#include <iostream>
// using namespace std; don't do this (its just lazy)
// Also its a bad habit to get into.
int main()
{
std::string message = "HELP";
// int password; I assume you want a password to be a string
std::string password;
std::cout << "Please enter password"\n; // Added \n to make it print nicely.
// cin<<password; The << is wrong should be >>
//
// Bu this reads a single word (separated by spaces).
// If you want the password to hold multiple words then you need
// to read the line.
std::getline(std::cin, password);
// if (password = message); This is assignment. You assign message to password.
// Also the ';' here means that nothing happens
// if it was true
//
// You are then trying to test the result of the
// assignment which luckily does not work.
// Use the '==' to test for equality.
if (password == message)
{
}
else
{
cout << "Please try again...";
}
// cin.ignor() This does nothing.
// What you are trying to do is get the program to wait
// for user input. You should do something like this:
std::cin.ignore(std::numeric_limits<std::streamsize>::max()); // Flush the buffer
std::cout << "Hit enter to continue\n";
std::cin.get();
}

You used the wrong operator on the if condition. You used = which is the assignment operator. You need to use == which is comparison. You also have a semi-colon after the if which doesn't belong and your braces for the statements aren't right,

Related

Stop taking input when a blank line encounters [closed]

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 2 years ago.
Improve this question
I am trying to stop the loop when user gives a blank line, otherwise push name and score to a vector pair. But this code is not working.
Input format:
<name><score>
e.g.:
Akash 45
My code is below:
int m;
cin>>m;
vector<pair<string,int>>player;
string name;
int score;
while(1)
{
cin>>name;
if(name.empty())
break;
cin>>score;
player.push_back(make_pair(name,score));
}
Also , I have tried the following:
if(name.length()==0)
while(getline(cin,name))
if (name=="")
None of them worked.
Can anyone help me?
`std::cin >>`
does not return with empty input. When the user wrote just the "Enter" key, the std::cin still wait.
I made the test, this is working :
std::getline(std::cin, name);
if(name.empty())
break;
Edit :
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::pair<std::string, int>>player;
std::string name;
int score;
while (1)
{
std::getline(std::cin, name);
if (name.empty())
break;
std::cin >> score;
player.push_back(make_pair(name, score));
// clear the std::cin buffer else the next std::getline won't wait next input
std::cin.seekg(0, std::ios::end);
std::cin.clear();
}
return 0;
}
the
std::cin.seekg(0, std::ios::end);
std::cin.clear();
fix the problem of the second std:getLine
operator>> ignores whitespace, and line breaks are treated as whitespace, so cin>>name will never return a blank string (baring an input failure).
To accomplish what you are attempting, you need to use get::getline() instead to read an entire line at a time. You can then test for blank lines, and can use std::istringstream to parse values from each non-blank line, eg:
vector<pair<string,int>> player;
string line, name;
int score;
while (getline(cin, line) && !line.empty())
{
istringstream iss(line);
if (iss >> name >> score)
player.push_back(make_pair(name, score));
}
There's a small program to demonstrate you how to achieve so:
#include <iostream>
#include <vector>
int main(void) {
std::string name;
std::vector<std::string> nameList;
std::getline(std::cin, name); // statement X
nameList.push_back(name);
for (; ;)
if (name.empty())
break;
else {
std::getline(std::cin, name); // recalling statement X again
nameList.push_back(name);
}
for (int i = 0; i < nameList.size(); i++)
std::cout << nameList[i] << std::endl;
return 0;
}
First of all, let the user input something before going inside the loop directly. As soon as the user hits Enter, the loop will be broken when name.empty() conditions becomes true and returns true and break statement is executed.
In the other hand, as long as the user will hit the Enter key and keep writing something line-by-line, the loop will be executed.
Notice that I've used a For loop in this case, you could do the same trick with a While loop as shown:
while (true)
if (name.empty())
break;
else {
std::getline(std::cin, name); // recalling statement X again
nameList.push_back(name);
}

I'm struggling with my If-statement using Atoi

I'm trying to make a ticket customer code, and I'm currently working with displaying my "customers". I want it to be like, if i type "blank, like nothing then enter" I want all of my customers in my own DTA file to be on my output. In other words displayed, to see which customers are registered.
void Customer::DisplayCustomer() {
cin.getline(buffer, MAXTEXT)
buffernr = atoi(buffer) //I need to convert text to numbers.
if (buffer[0]=='A' && buffer[1] == '\0')
// (Here I have a function which displays everything) don't focus on this one
}
What I'm asking is, what do i have to type, in order for my code to understand that I want to have a if statement for someone who presses Enter without typing anything my display customer function will run. I've also tried (If buffer[0]=='\n') but that won't work either.
It seems you want to use std::getline() rather than std::istream::getline() for your use case:
void Customer::DisplayCustomer() {
std::string buffer;
std::getline(std:cin,buffer);
std::istringstream iss(buffer);
int buffernr;
if(!(iss >> buffernr)) { // This condition would be false if there's no numeric value
// has been entered from the standard input
// including a simple ENTER (i.e. buffer was empty)
// (Here i have a function which displays everything) don't focus on this
// one
}
else {
// Use buffernr as it was parsed correctly from input
}
}
This code checks if the buffer is empty
#include <iostream>
int MAXTEXT{300};
int main() {
char buffer[MAXTEXT];
std::cin.getline(buffer, MAXTEXT);
if (buffer[0] == '\0') {
std::cout << "Empty" << std::endl;
}
return 0;
}
A better solutions with std::string is
#include <string>
#include <iostream>
int main() {
std::string buffer;
std::getline(std::cin, buffer);
if (buffer.empty()) {
std::cout << "Empty" << std::endl;
}
return 0;
}

getline() function is not working in while loop

I want to make a simple file input output program with an external class "File_Opening_and_Closing.cpp” when I use ”getline ()” function without any loop it works fine but when I use ”getline ()” function with do while loop in “main.cpp” it crushes.
Please tell me where the problem is and how I solve it?
main.cpp
#include<iostream>
#include<fstream>
#include "File_Opening_and_Closing.h" using namespace std;
int main() {
int i=1;
char file_make='y';
char file_insert='y';
do
{
File_Opening_and_Closing file[i];
do
{
file[i].put_data();
file[i].show_data();
cout<<"Do you want to insert text again ? 'y' OR 'n'"<<endl;
cin>>file_insert;
}while(file_make=='y');
i++;
cout<<"Do you want to Make another file ? 'y' OR 'n'"<<endl;
cin>>file_make;
}while(file_insert=='y');
return 0;}
with out loop working fine >>
int main() {
File_Opening_and_Closing file;
file.put_data();
file.show_data();
return 0;}
File_Opening_and_Closing.cpp
#include "File_Opening_and_Closing.h"
File_Opening_and_Closing::File_Opening_and_Closing()
{
cout<<"Enter the file name and type => ";
cin>>file_name;
}
void File_Opening_and_Closing::put_data(){
ofstream file_out;
file_out.open(file_name);
cin.ignore();
cout<<"Enter the string => ";
cin.ignore();
// getline is not working here!
getline(cin,data);
data = "Hello World!";
file_out<<data;
file_out.close();
}
void File_Opening_and_Closing::show_data(){
ifstream file_in;
file_in.open(file_name);
getline(file_in,data);
cout<<data;
file_in.close();
}
File_Opening_and_Closing.h
#ifndef FILE_OPENING_AND_CLOSING_H
#define FILE_OPENING_AND_CLOSING_H
#include<iostream>
#include<fstream>
using namespace std;
class File_Opening_and_Closing
{
private:
string file_name;
string data;
public:
File_Opening_and_Closing();
void put_data();
void show_data();
protected:
};
#endif // FILE_OPENING_AND_CLOSING_H
Problem picture
You have a whole host of issues, not the least of what is a How to debug small programs issue where you have mixed up the variables used to test both do .. while (...); loops, e.g.
...
cin>>file_insert;
}while(file_make=='y');
// i++; (not needed and VLA's not allowed in C++
cout<<"Do you want to Make another file ? 'y' OR 'n'"<<endl;
cin>>file_make;
}while(file_insert=='y');
Secondly, as mentioned in the comments, Standard C++ does not allow Variable Length Arrays.
File_Opening_and_Closing file[i];
If you need more than 1 instance of your class, the use a vector of classes or array of classes. However, there is no need in your code for either. Since you create a new instance of File_Opening_and_Closing each iteration through the do { ... } while (..); loop, you can simply use:
File_Opening_and_Closing file;
You are making things incredibly hard on yourself by declaring file_make and file_insert as type char. Instead, simply make them std::string and test with, e.g. if (file_make == "y"). This will allow you to read all input with getline avoiding the problems with mixed std::cin and getline use.
The remaining issues are a complete failure to validate the file openings with, e.g. if (!file_out.is_open()) { /* handle error */ } with similar tests needed for each input to ensure you can trap a input cancellation by the user generating a manual EOF with Ctrl+d (or Ctrl+z on windows).
Also, avoid putting using namespace std; in header files. There is no need to pull the standard namespace into every file utilizing your header (though you did do a good job and protect against multiple inclusions with the header guards FILE_OPENING_AND_CLOSING_H). In fact there is no reason for using namespace std; at all here. Just use the std:: namespace resolution operator for cin, cout, etc..
Leaving the validations for you to add, addressing the other issues, you could do something similar to:
File_Opening_and_Closing.h
#ifndef FILE_OPENING_AND_CLOSING_H
#define FILE_OPENING_AND_CLOSING_H
#include<iostream>
#include<fstream>
class File_Opening_and_Closing
{
private:
std::string file_name;
std::string data;
public:
File_Opening_and_Closing();
void put_data();
void show_data();
protected:
};
#endif
File_Opening_and_Closing.cpp
#include "File_Opening_and_Closing.h"
File_Opening_and_Closing::File_Opening_and_Closing()
{
std::cout << "Enter the file name and type => ";
getline (std::cin, file_name);
}
void File_Opening_and_Closing::put_data(){
std::ofstream file_out;
file_out.open(file_name);
std::cout<<"Enter the string => ";
getline (std::cin, data);
file_out << data << '\n';
file_out.close();
}
void File_Opening_and_Closing::show_data(){
std::ifstream file_in;
file_in.open (file_name);
getline (file_in,data);
std::cout << data << '\n';
file_in.close();
}
main.cpp
#include<iostream>
#include<fstream>
#include "File_Opening_and_Closing.h"
int main (void) {
std::string file_make = "y";
std::string file_insert = "y";
do
{
File_Opening_and_Closing file;
do
{
file.put_data();
file.show_data();
std::cout << "Do you want to insert text again ? 'y' OR 'n'\n";
getline (std::cin, file_insert);
} while (file_insert == "y");
std::cout << "Do you want to Make another file ? 'y' OR 'n'\n";
getline (std::cin, file_make);
} while (file_make == "y");
return 0;
}
It will now create as many files as you need (though you will want to look into std::ios::app mode if you want to add more than one string.
Example Use/Output
$ ./bin/main
Enter the file name and type => out1
Enter the string => foobar
foobar
Do you want to insert text again ? 'y' OR 'n'
y
Enter the string => barbaz
barbaz
Do you want to insert text again ? 'y' OR 'n'
n
Do you want to Make another file ? 'y' OR 'n'
y
Enter the file name and type => out2
Enter the string => bazbuz
bazbuz
Do you want to insert text again ? 'y' OR 'n'
n
Do you want to Make another file ? 'y' OR 'n'
n
Resulting Output Files
$ cat out1
barbaz
$ cat out2
bazbuz
Let me know if you have further questions.

C++ multiple line input from keyboard

For an assignment of mine, we're suppose to take in several lines of input from the keyboard. For example:
Please enter your name: (this is static. Always 1 input)
Justin
Please enter the names: (this can be any number of inputs, smallest being 1)
Joe
Bob
John
Jackson
In the end, I want to compare the named entered at the beginning with all of the names entered in after. I tried using getline and cin, but that seems to only work if I know the exact number of names I expect to be entered. Can anyone guide me in the right direction please. Thank you
Try this
void read_lines( std::istream& in, std::list< std::string >& list ) {
while( true ) {
std::string line = "";
std::getline( in, line );
if( line != "" ) {
list.push_back( line );
} else {
break;
}
}
}
You should have added some rough code showing your efforts on doing the assignment.
However, I will provide you with some initial naive code (please read the comments inside!):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string name, temp;
vector<string> names; // this is just one of the possible container that you can use
bool result = false; // flag used to store the result of the matching operation (default: false)
// first we ask the user to enter his/her name
cout << "Please enter your name:" <<endl;
cin >> name;
// then we need something a little bit more complicated to look for variable number of names
cout << "Please enter the names:" <<endl;
while(cin)
{
cin >> temp;
names.push_back(temp);
}
// This for-loop is used to go through all the input names for good-match with the user name
for( int i = 0; i < names.size(); i++ )
{
temp = names.front();
if (name == temp) result = true; // change the flag variable only in case of match
}
cout << "Valid match: " << (result?"yes":"no"); // ternary operator
}
You did not provide in your question enough details.. so the above code may not fully fit your requirements!

How to validate numeric input in C++

I'd like to know how to limit an input value to signed decimals using std::cin.
double i;
//Reading the value
cin >> i;
//Numeric input validation
if(!cin.eof())
{
peeked = cin.peek();
if(peeked == 10 && cin.good())
{
//Good!
count << "i is a decimal";
}
else
{
count << "i is not a decimal";
cin.clear();
cin >> discard;
}
}
This also gives an error message with the input -1a2.0 avoiding the assignation of just -1 to i.
If the backing variable of the cin is a number, and the string provided is not a number, the return value is false, so you need a loop:
int someVal;
while(!(cin >> someVal)) {
cin.reset();
cout << "Invalid value, try again.";
}
Combining the techniques from the top answer here and this website, I get
input.h
#include <ios> // Provides ios_base::failure
#include <iostream> // Provides cin
template <typename T>
T getValidatedInput()
{
// Get input of type T
T result;
cin >> result;
// Check if the failbit has been set, meaning the beginning of the input
// was not type T. Also make sure the result is the only thing in the input
// stream, otherwise things like 2b would be a valid int.
if (cin.fail() || cin.get() != '\n')
{
// Set the error state flag back to goodbit. If you need to get the input
// again (e.g. this is in a while loop), this is essential. Otherwise, the
// failbit will stay set.
cin.clear();
// Clear the input stream using and empty while loop.
while (cin.get() != '\n')
;
// Throw an exception. Allows the caller to handle it any way you see fit
// (exit, ask for input again, etc.)
throw ios_base::failure("Invalid input.");
}
return result;
}
Usage
inputtest.cpp
#include <cstdlib> // Provides EXIT_SUCCESS
#include <iostream> // Provides cout, cerr, endl
#include "input.h" // Provides getValidatedInput<T>()
int main()
{
using namespace std;
int input;
while (true)
{
cout << "Enter an integer: ";
try
{
input = getValidatedInput<int>();
}
catch (exception e)
{
cerr << e.what() << endl;
continue;
}
break;
}
cout << "You entered: " << input << endl;
return EXIT_SUCCESS;
}
Sample run
Enter an integer: a
Invalid input.
Enter an integer: 2b
Invalid input.
Enter an integer: 3
You entered: 3.
cin's >> operator works by reading one character at a time until it hits whitespace. That will slurp the whole string -1a2.0, which is obviously not a number so the operation fails. It looks like you actually have three fields there, -1, a, and 2.0. If you separate the data by whitespace, cin will be able to read each one without problem. Just remember to read a char for the second field.
I tried many techniques for reading integer input from the user using the >> operator, but in a way or another all my experiments have failed.
Now I think that getline() function (not the method with the same name on std::istream) and the strtol() function from the include cstdlib is the only predictable consistent solution for this problem. I would appreciate if someone proved me wrong. Here is something like the one I use:
#include <iostream>
#include <cstdlib>
// #arg prompt The question to ask. Will be used again on failure.
int GetInt(const char* prompt = "? ")
{
using namespace std; // *1
while(true)
{
cout << prompt;
string s;
getline(cin,s);
char *endp = 0;
int ret = strtol(s.c_str(),&endp,10);
if(endp!=s.c_str() && !*endp)
return ret;
}
}
*1: Placing using namespace whatever; to the global scope may lead to broken "unity builds" (google!) on larger projects, so should be avoided. Practice to not use that way, even on smaller projects!
Reading integers from files is a very different matter. Raúl Roa's approach can be good for that if properly worked out. I also suggest that wrong input files should not be tolerated, but it really depends on the application.
Be warned that using >> and getline() in the same program on cin will lead to some problems. Use one of them only, or google to know how to handle the issue (not too hard).
Something like:
double a;
cin >> a;
Should read your signed "decimal" fine.
You'll need a loop and some code to make sure it handles invalid input in a sensible way.
Good luck!