how to insert a word and use it to make comparison in if condition in c++ - c++

i want to use the word i insert to use it to make comparison in if condition to show some word it the comparison is true.
here is my code
#include <iostream>
using namespace std;
int main()
{
char u[5];
cout<<" p " <<" c "<<" U "<<endl;
cout<<" pepsi=5"<<" coca=3"<<" 7-UP=2"<<endl;
cout<<"CHOOSE your drink"<<endl;
cin>>u;
if (u=="pepsi")
cout<<"your choice is pepsi and ur bill is 5 ";
}

First in the future I would suggest trying to be more specific on what your problem is and what you don't understand. Just saying I want to do X and here is my code is giving us very little to work with and we are basically just guessing on what you are having problems with.
Now on to what I believe you are having problems with (I am assuming since you didn't tell us what is going wrong).
In this case you are using a character array with a length of 5. Now when you use character arrays you need to take into account that all the reasonable inputs that that variable might store will actually fit into that character array.
Let's look at pepsi. You might think it would fit but in fact it doesn't because you are forgetting about the null character that is added on the end. This is what it looks like.
u[0] = 'p'
u[1] = 'e'
u[2] = 'p'
u[3] = 's'
u[4] = 'i'
u[5] = '\0'
So as you can see there is actually 6 characters in this word which will cause a overflow. I am assuming this is your problem.
Now how do we fix this? As others have said in the comments if you are using C++ it is probably better for you to use std::string for this problem since it will hide from you most of the problems you have to do deal with when using C style string (What you are using now). Then once you feel more comfortable with the language you can come back and revisit C style strings.
With std::string it would look something like this. Remember that when testing strings case matters (IE "string" is not the same as "String").
std::string choice;
std::cin >> choice;
if (choice == "pepsi")
{
std::cout << "You selected pepsi!" << std::endl;
}
Hope that helps a little and fixes your problems.

Related

Why does getline behave weirdly after 3 newlines?

I'll preface this by saying I'm relatively new to posting questions, as well as C++ in general, my title is a little lame as it doesn't really specifically address the problem I am dealing with, however I couldn't really think of another way to word it, so any suggestions on improving the title is appreciated.
I am working on a relatively simple function which is supposed to get a string using getline, and read the spaces and/or newlines in the string so that it can output how many words have been entered. After reaching the character 'q' it's basically supposed to stop reading in characters.
void ReadStdIn2() {
std::string userInput;
const char *inputArray = userInput.c_str();
int count = 0;
getline(std::cin, userInput, 'q');
for (int i = 0; i < strlen(inputArray); i++){
if ((inputArray[i] == ' ') || (inputArray[i] == '\n')){
count += 1;
}
}
std::cout << count << std::endl;
}
I want to be able to enter multiple words, followed by newlines, and have the function accurately display my number of words. I can't figure out why but for some reason after entering 3 newlines my count goes right back to 0.
For example, if I enter:
hello
jim
tim
q
the function works just fine, and returns 3 just like I expect it to. But if I enter
hello
jim
tim
bill
q
the count goes right to 0. I'm assuming this has something to do with my if statement but I'm really lost as to what is wrong, especially since it works fine up until the 3rd newline. Any help is appreciated
The behaviour of the program is undefined. Reading input into std::string potentially causes its capacity to increase. This causes pointers into the string to become invalid. Pointers such as inputArray. You then later attempt to read through the invalid pointer.
P.S. calculating the length of the string with std::strlen in every iteration of the loop is not a good idea. It is possible to get the size without calculation by using userInput.size().
To fix both issues, simply don't use inputArray. You don't need it:
for (int i = 0; i < userInput.size(); i++){
if ((userInput[i] == ' ') || (userInput[i] == '\n')){
...

Visual C++ using Console: Char/String compatibility issues with while loop

cout << "Would you like to make another transaction? (y/n)" << endl;
cin >> repeat_transaction;
static_cast<char>(repeat_transaction);
while (repeat_transaction != 'y' && repeat_transaction != 'n')
{
cout << "Invalid selection: Please enter y or n";
cin >> repeat_transaction;
static_cast<char>(repeat_transaction);
}
During the Invalid selection loop, I once accidentally pressed "mn". I noticed the console read out Invalid selection..., So, it did in fact finish and re-enter the while loop. However, after this the console terminated the program. If you enter a single character 'a' or 'y' or 'n' it acts just as it should. Ending or not ending. This was before I attempted to use static_cast to force the truncation of the user input.
Since you managed to get this program to compile I can only assume that repeat_transaction was specified as a char and not a std::string.
When you use cin to get a character it only gets one character but it doesn't flush the buffer. I believe you understand this issue since you wrote This was before I attempted to use static_cast to force the truncation of the user input. . You can attempt to use cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); instead of static_cast<char>(repeat_transaction); after each call to cin >> repeat_transaction; . There are downsides to this. If you enter 'mn' it will work as expected. It reads the m which is not y or n and then flushes the extra characters until it finds end of line \n. If you do nm, n will match and the m will be thrown away. So in that case it will accept nm as valid and exit the loop.
There are other ways that may be easier and give you the effect closer to what you are looking for. Instead of reading a character at a time you can read an entire line into a string using getline (See the C++ documentation for more information). You can then check if the length of the string is not equal to 1 character. If it's not length 1 then it is invalid input. If it is 1 then you want to check for y and n. Although basic (and not overly complex) this code would do a reasonable job:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string repeat_transaction;
cout << "Would you like to make another transaction? (y/n)" << endl;
getline(cin, repeat_transaction);
while (repeat_transaction.length() != 1 || (repeat_transaction != "y" && repeat_transaction != "n"))
{
cout << "Invalid selection: Please enter y or n";
getline(cin, repeat_transaction);
}
return 0;
}
I said reasonable job since one deficiency you might see is that you want to trim white spaces from the beginning and end. If someone enters n or y with a space or tab in front it will be seen as invalid (whitespace at the end would be similar). This may not be an issue for you, but I thought I would mention it.
On a final note, you may have noticed I used using namespace std;. I did so to match what was in the original question. However, this is normally considered bad practice and should be avoided. These StackOverflow answers try to explain the issues. It is better to not do it and prepend all standard library references with std::. For example string would be std::string, cin would be std::cin etc.

Wrong Output : counting the string

#include <iostream>
#include <cstring>
using namespace std;
int main() {
char a[10001],b[10001];
int tot,s1,s2;
cin>>tot;
while(tot!=0) {
gets(a);
gets(b);
s1= strlen(a);
s2= strlen(b);
cout<<s1<<s2<<endl;
tot--;
s1=0;
s2=0;
}
}
this is a program to find length of two strings , with cases also entered
Input :
4
abcd
xyz
abcd
bcda
aabc
acaa
Codechef
elfedcc
Expected output
43
44
44
87
but output is
04
34
44
48
Why?
As noted in the comment, the compiler is punishing you for using gets1. I wasn't going to write an actual answer, but the answers you're getting seem to be trying to cover up the problems with the code, without actually fixing anything.
First: never use gets. There's simply no way to use it safely, and no excuse for even trying. It's just a badly designed function and we'd all be better off if it had never existed.
Second, in C++ there's almost never a good reason to use arrays of char for strings. strlen is pretty much the same way. These aren't as dangerous or horrible as gets but real reasons to use them in C++ (outside of things like extremely limited embedded systems) is sufficiently rare that until you know what you're doing and why, it's probably best to forget that they even exist as well.
While you're at it, using a while loop (counting down, no less) in a case like this mostly just obfuscates the code while gaining nothing in return. For that matter, using a variable name like tot instead of (for example) total or (better) pair_count is kind of silly as well.
So, having gotten bombastic about what you shouldn't do, what would I suggest instead? First, if you're going to use stream >> var type input, try to use it consistently. If you're going to read lines instead, try to do that consistently. In this case, you can use either one, but mixing the two leads to exactly the sort of problem you're having right now. As such, it's best to avoid that whole area if you can (and you almost always can).
For this, I'd use >> throughout, use std::string to hold the strings, and a for loop to execute the fixed number of iterations:
int word_count;
std::cin >> pair_count;
for (int i=0; i<pair_count; i++) {
std::string a, b;
std::cin >> a >> b;
std::cout << a.size() << b.size() << '\n';
}
Unlike the other recommendations you've gotten, this is typesafe (scanf and company don't even try to be), safe from buffer overflows (gets never is, and while scanf and company can be, they aren't when used as the other answers have recommended). It's also shorter and simpler without adding mostly-unexplained patches to cover up the real problems in the code.
If the preceding sounds harsh, I apologize for that. Unfortunately, that's sometimes just about necessary to get the point across, and at least to me, this seems like one of those times.
1. The zeroth commandment: thou shalt not use gets. If you do, you shall surely die (but not as soon as everybody maintaining your code wishes you had).
You should really try using the standard template library for string things:
std::string a, b;
int numberToAsk = 0;
cin >> numberToAsk;
while(numberToAsk!=0) {
cin >> a >> b;
cout << a.size() << ", " << b.size() << endl;
--numberToAsk;
}
(also make sure to use std::vector in stead of plain arrays!)
Also, you can avoid needing to ask for the number of entries upfront by just checking if standard input is still ok; your program will end as soon as you end the input stream (e.g. ctrl+z or F6 on windows, or ctrl+d on linux):
while(cin >> a >> b) {
cout << a.size() << ", " << b.size() << endl;
}
cin>>tot;
This code does not consume '\n' character. So the first gets call reads line between "4" and "\n". To see it you may try input
4abcd
xyz
abcd
bcda
aabc
acaa
Codechef
elfedcc
change cin to scanf works
#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;
int main() {
char a[10001],b[10001];
int tot,s1,s2;
scanf("%d\n",&tot);
while(tot!=0) {
gets(a);
gets(b);
s1= strlen(a);
s2= strlen(b);
cout<<s1<<s2<<endl;
tot--;
s1=0;
s2=0;
}
}
Do it this way
scanf("%d ",%t);
For taking in no. of inputs. That space avoids '\n' character that you enter after entering a number input which is taken by first string. Rest of your code can be done as it is.
You need to include cstdio header. #include<cstdio>

Validating a string to be all digits

Hi I'm having trouble validating this string to be all decimals, even if I type in 9999 it still tell me my if statement comes out false. I think it's a typo but I don't know where.
cout<<"Enter a very large number"<<endl;
cin>>In1; //inputs a string
for(int i=0; 0<In1.length();i++){ //the loop that goes thru each index
if (!(isdigit(In1[i]))){ //validates each index
//tells the user to try again
cout<<"You did not enter a valid input, please try again"<<endl;
In1="";
cin>>In1;
i=0;//starts the loop over if reached
}
}
I keep receiving the "You did not enter a valid input, please try again" regardless of whether I type it right or wrong.
for(int i=0; 0<In1.length();i++){
See what you did? Change to
for(int i=0; i<In1.length();i++)
In your loop condition you need to compare i with In1.length().
You might want to change
0<In1.length()
to
i<In1.length()
Using
#include<algorithm>
if ( std::find_not_if( in1.begin(), in1.end(), isdigit ) != in1.end() ){ ...
might have prevented this unfortunate incident, and is also quite clear on the intent. The dual _not/!= muddles it slightly but still.
There are quite a few convenience algorithms, replacing common uses for simple for- statements. Most of them are on the form
do_this( where_to_start, where_to_end, do_this_operation )
There is usually nothing special or dramatic with these function, they apply the operation to each element in the start-end sequence.
You have find, count, copy, and generate to mention a few. Their purpose is to clarify the intent of your for-statement. You can find a complete list at http://en.cppreference.com/w/cpp/algorithm
You will almost certainly find that, over time, you become more adept at seperating different parts of code into the functionality that they each provide. Making debugging and later modification considerably easier.
It also makes, as Captain Giraffe points out, the intent of the code considerably more clear - something that can only make reading the code easier & quicker.
I've not used std::find_not_if, opting instead to use the method that you've chosen (based on the assumption that the important thing is knowing how to get the right answer, as opposed to simply supplying the right answer - well, that and me not knowing of find_not_if's existence :grin:) You'll see that I've chucked it into it's own function, which I call from main. The function also only performs a single task - that of checking the validity of the string. Any attempt to prompt the user for this text, re-prompt in the case of error and finally, take action on the correct input is the sole responsibility of the code that calls isValidNumericalString - there's no reason you couldn't throw those functions into their own functions, as opposed to having a single, large body of main.
#include <iostream>
using namespace std;
// returns true if all characters in string are numerical (0-9)
bool isValidNumericalString(string inputString)
{
int i, n = inputString.length();
for (i=0; i<n; i++)
if ( !isdigit(inputString[i]) )
return false;
return true;
}
int main()
{
string In1;
cout << "Enter a very large number (digits 0-9 only. 10e1 is unacceptable): ";
cin >> In1;
while (!isValidNumericalString(In1))
{
cout << "You did not enter a valid input, please try again :p" << endl;
cout << "Enter a very large number (digits 0-9 only. 10e1 is unacceptable): ";
cin >> In1;
}
cout << "Congratulations - '" << In1 << "' is a valid string representation of a number" << endl;
return 0;
}

C++ converting character in vector to an integer...tough, need help?

This is what I have:
char userInput;
int position;
vector<string> userVector(7);
vector<int> someVector(7,1);
cin >> userInput;
cin >> position;
if(userInput == 'X')
userVector[position] = '1';
if(userVector[position]-someVector[position] == 0)
cout << "Success"
My problem is that userVector[position] is actually a character, because userVector is a string vector. However, I need this calculation to take place (userVector[position] - someVector[position]) because I need to determine if the outcome is 0 or some other number. Any help?
In case it doesn't make sense here, userVector HAS to be a string vector, because it's part of the requirements for this program. Basically, a user is supposed to be allowed to enter an "X" anywhere in the userVector vector, and you have to tell them if it matches expected outputs.
So, in this case, the "expected output" would be someVector, which has a 1 in all of it's spaces. What I'm trying to do is subtract the two vectors so that if the user enters anything other than X, the vector subtraction will not equal 0, and consequently, result in the program doing something different.
Hope that clears things up!
If I understand correctly your code, you are trying to convert a string representing a decimal number into an integer. You have several ways of doing that; e.g., by using istringstream:
int num;
if (!(istringstream(userInput[position]) >> num))
num = 0;
if (n - someVector[position] == 0) {
...
or you could use good old atoi:
if (atoi(userInput[position].c_str()) - someVector[position] == 0) {
If I am wrong about what you are trying to do, please clarify what you are trying to do...
I can't figure out what you're trying to do from your statement of the
problem. The expression userInput[position] isn't legal, since
userInput isn't a pointer, nor anything that can be converted to a
pointer.
But your code doesn't seem to correspond to the textual description,
since you describe userInput as a string vector
(std::vector<std::string>?), but the code declares it as a char.