Using GETS and CIN together - c++

trying to take 2 different space separated number input as a string, concatenate them and print final string. somehow the input always messes up...
#define SORT(a) sort(a.begin(),a.end())
using namespace std;
int main()
{
int level, count = 0;
cin >> level;
string lx, ly, f;
getline(cin, lx);
getline(cin, ly);
f = lx + " " + ly;
SORT(f);
int size = f.size();
cout << f << endl << size << endl << level << endl;
return 0;
}

Why are you sorting them if all you want to do is combine them and print them?
Your initial code without the SORT() works perfectly.
I am not sure since I never use it, but I believe sort will sort all characters in the string alphabetically, so dfg acb will become abcdfg

Related

Taking an input string, converting it to its hex value, then storing its hex as an int

So I'm trying to make a program that asks a user for a planet, this is stored as a string. I want to use a switch statement to make decisions (like if it's earth do this, if it's mars do this). I am aware that switch statements only take ints, so I took the string and translated it to its hex value. The issue I'm stuck on is how do I have the hex value saved as an int.
I am aware that it would be way easier to do a bunch of nested if statements, but I find that really ugly and bulky.
Here is what I have so far:
/*
* Have user input their weight and a planet
* then output how heavy they would be on that planet
* if planet is wrong
* output it
*/
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string returnanswer(string x) {
string dat = x;
int test;
ostringstream os;
for (int i = 0; i < dat.length(); i++)
os << hex << uppercase << (int) dat[i];
string hexdat = os.str();
cout << "Text: " << dat << endl;;
cout << "Hex: " << hexdat << endl;
return hexdat;
}
int main() {
int weight;
string planet;
cout << "Please enter your weight: " << endl;
cin >> weight;
cout << "Please enter Planet" << endl;
cin >> planet;
returnanswer(planet);
return 0;
}
One way to convert a string hex to an int (using the suggestion from C++ convert hex string to signed integer) would be this:
unsigned int num;
stringstream ss;
ss << hex << hexdat;
ss >> num;
num would now contain the int value of hexdat.
On a side note, instead of converting the planet name to a hex and then to a string, you should consider using an unordered_map (as others have suggested), for example unordered_map<string, Enum> that maps user input planet names to Enum values. The planet Enum would look something like this:
enum Planet {mercury, venus, earth, mars, jupiter, saturn, uranus, neptune};

Use of cin and getline for strings

I was recently doing a problem in C++:
Write a program to work out if a series of 5 digits are consecutive
numbers. To make this easier, assumes the digits are a string:
string numbers = "10-9-8-7-6";
Make sure your code works for the following sequence, as well:
string numbers = "1-2-3-4-5";
I solved it, however I saw when I used cin for the string the console window threw some exception & didn't execute the program but on replacing it with getline, it worked perfectly.
Could anyone explain me the reason behind it because logically both should work properly.
The program is:
#include<iostream>
#include<string>
using namespace std;
void change(int x, int y, int &inc, int &dec)
{
if (x - y == 1)
++dec;
else if (y - x == 1)
++inc;
}
int main()
{
string s = "", snum = "";
cout << "enter 5 nos and use \'-\' to separate them: ";
cin >> s;
int i = 0, x = 0, y = 0, inc = 0, dec = 0;
for (char &ch : s)
{
if (ch == '-')
{
++i;
if (i == 1)
{
y = stoi(snum);
cout << y << endl;
}
else
{
x = y;
y = stoi(snum);
cout << x << " " << y << endl;
change(x, y, inc, dec);
}
snum = "";
}
else
snum += ch;
}
x = y;
y = stoi(snum);
cout << x << " " << y << endl;
change(x, y, inc, dec);
if (inc == 4 || dec == 4)
cout << "ORDERED";
else
cout << "UNORDERED";
return 0;
}
If you have to enter everything at the same time such as:
10 9 8 7 6
All on one line then cin does not record all that at the same time.
Concerning cin it only takes the characters before a space (" ") for example. Getline however takes that entire line and uses it. Another way to do the same thing would be to use the cstdio library and have it set up with either using printf or puts to prompt, and then use gets to gather all the information from the puts prompt. This is what I assume why it works.
Example:
cstdio library
char string[50];
printf("Enter a string of text");
gets(string);
cout << string << endl;
*EDIT
After the comment below I realized what you are asking, and if you are assuming the numbers are strings, and they are separated with hyphens and no spaces then it should work fine. It shouldn't be the problem of cin by maybe something else?
If there are spaces involved in your code then what I wrote above EDIT will be a simple solution to THAT problem.
If you need to get a formatted string, I recommend you scanf like this:
if( 5 == scanf("%d-%d-%d-%d-%d", &a, &b, &c, &d, &e) )
//welldone
// work with above 5 int easily :)
else
// Please enter again
This way you don't have to work with string at all and life would be easier.
You can easily check if these 5 are consecutive or not .
If you need not a new solution and want to get your code fixed, tell me in comment.

C++ printing spaces or tabs given a user input integer

I need to turn user input (a number) into an output of TAB spaces.
Example I ask user:
cout << "Enter amount of spaces you would like (integer)" << endl;
cin >> n;
the (n) i need to turn it into an output like:
cout << n , endl;
and what prints on the screen would be the spaces
ex
input is 5
out put |_| <~~~there are five spaces there.
Sorry If I can't be clear, probably this is the reason I haven't been able to find an answer looking through other people's questions.
any help will be greatly appreciated.
Just use std::string:
std::cout << std::string( n, ' ' );
In many cases, however, depending on what comes next, is may be
simpler to just add n to the parameter to an std::setw.
cout << "Enter amount of spaces you would like (integer)" << endl;
cin >> n;
//print n spaces
for (int i = 0; i < n; ++i)
{
cout << " " ;
}
cout <<endl;
You just need a loop that iterates the number of times given by n and prints a space each time. This would do:
while (n--) {
std::cout << ' ';
}
I just happened to look for something similar and came up with this:
std::cout << std::setfill(' ') << std::setw(n) << ' ';
You can use C++ manipulator setw(n) function which stands for set width to print n spaces.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n;
std::cin>>n;
cout<<"Here is "<<n <<" spaces "<<setw(n)<<":";
}
And don't forget to include C++ Library -
enter image description here
Appending single space to output file with stream variable.
// declare output file stream varaible and open file
ofstream fout;
fout.open("flux_capacitor.txt");
fout << var << " ";
Simply add spaces for { 2 3 4 5 6 } like these:
cout<<"{";
for(){
cout<<" "<<n; //n is the element to print !
}
cout<<" }";

C++ program to accept multiples inputs and put in an array using pointer

there's a problem facing me in this question :
"write a c++ console program to accept five
integers values from keyboard in one line separated by spaces . the program then stores the five values in an array using pointer . then print the elements of the array on the screen ."
I tried to make a string variable and accept 5 integers from user then convert it to integer but it doesn't work well because it doesn't take numbers after space .
any help guys ??
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
string numbers;
getline(cin, numbers);
int arr[5];
int *ptr;
int values;
stringstream convert(numbers);
convert >> values;
cout << values;
}
It will only take one at a time, you need to add more calls to convert like so:
stringstream convert(numbers);
convert >> values;
cout << values;
convert >> values;
cout << " " << values;
convert >> values;
cout << " " << values;
The C++faq has a good section on this.
Without major modification, if you need to put the number directly into the array using a pointer, you can do this:
int *ptr = arr ;
convert >> *ptr++ ;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
for( unsigned int i = 0; i < 5; ++i )
{
cout << arr[i] << " " ;
}
cout << std::endl ;
I successfully made it
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
int arr[5];
string number;
cout << "Please enter 5 integers separeted with spaces " << endl;
getline(cin, number);
int *ptr = arr ;
stringstream convert(number);
convert >> *ptr++ ;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
for( int i = 0; i < 5; ++i )
{
cout << arr[i] << " " ;
}
cout << std::endl ;
}
I the numbers variable is string you can search for first non space character using numbers.find_first_not_of(" "); and first space character by numbers.find_first_of(" "); then create a subset using substr(.....) now place the substr in another string variable. Now convert the substring to int. repeat the steps for number of times you need. i.e. place the whole code inside a while loop. Terminate the loop whenever numbers.find_first_of(" ");returns numbers.end()

C++ How to check an input float variable for valid input

I'm writing a program that acts as a calculator; based on the character input by the user it performs a certain operation. The structure of the program seems to work fine, but I'd like to be able to check for erroneous input. After receiving the float variable, is there any way to check if it does not contain any characters other than digits and decimals? I've tried isdigit, and this:
if (!(cin >> x)) {
cout << "You did not enter a correct number!" << endl;
return;
}
But nothing seems to be working.
Here is a sample of one of the simple operation functions I'm using:
void Add(){
float x = 0, y = 0, z = 0;
cout << "Please enter two numbers you wish "
<< "to add separated by a white space:" << endl;
cin >> x >> y;
z = x+y;
cout << x << " + " << y << " = " << z << "." << endl;
return;
}
You test the state of the stream:
float x, y;
if (std::cin >> x >> y) {
// input extraction succeeded
}
else {
// input extraction failed
}
If this isn't working for you, then you need to post the exact code that isn't working.
To detect erroneous string input where you expected a number, C++ doesn't automatically know what you want, so one solution is to first accept your input as strings, validate those strings, then if valid, only then convert the strings to float numbers using the atof() function.
The standard string class has a function called find_first_not_of() to help you tell C++ which characters you consider valid. If the function finds a character not in your list, it will return the position of the bad character, otherwise string::npos is returned.
// add.cpp
#include <iostream>
#include <string>
#include <cstdlib> // for atof()
using namespace std;
void Add()
{
cout << "Please enter two numbers you wish "
<< "to add, separated by a white space:"
<< endl;
string num1, num2;
cin >> num1;
if( num1.find_first_not_of("1234567890.-") != string::npos )
{
cout << "invalid number: " << num1 << endl;
return;
}
cin >> num2;
if( num2.find_first_not_of("1234567890.-") != string::npos )
{
cout << "invalid number: " << num2 << endl;
return;
}
float x = 0, y = 0, z = 0;
x = atof( num1.c_str() );
y = atof( num2.c_str() );
z = x+y;
cout << x << " + " << y << " = " << z << "." << endl;
}
int main(void)
{
Add();
return 0;
}
One possibility would be to read the input as a string, then use boost lexical_cast to convert to floating point. lexical_cast only considers the conversion successful if the entire input converts to the target -- otherwise, it'll throw a bad_lexical_cast exception.
Another idea would be to test the input against a regex. An example regex for a float could be
-?[0-9]+([.][0-9]+)?
This method would also make it easier to refine the matching mechanism by only modifying the regex, and you could map multiple regular expressions against different types of input, for example an integer could then be expressed as
-?[0-9]+
and so on. Keep in mind however, that this only tests if the input is a valid format, it still requires a numerical conversion afterwards (I prefer boost::lexical_cast).
(You can also try it out with http://gskinner.com/RegExr/)