Problem:
So the first windows shows up asking what day it is. I type in the day and the only thing that pops up is the error message telling me to check my spelling and punctuation. Why aren't the windows with the actual soups of the day showing up?
//*****************************************************************************
public class IfSoupDay {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String day = JOptionPane.showInputDialog(null,"I am going to tell you"
+ " what the soup of the day is."+ "\n"
+ "\n"+"What day of the week is it?");
if (day == "Monday")
JOptionPane.showMessageDialog(null, "The soup of the day is Lobster Soup");
else if(day == "Tuesday")
JOptionPane.showMessageDialog(null,"The soup of the day is Potato Soup");
else if (day == "Wednesday")
JOptionPane.showMessageDialog(null, "The soup of the day is Chicken Noodle Soup");
else if (day == "Thursday")
JOptionPane.showMessageDialog(null, "The soup of the day is Goat Soup");
else if (day == "Friday")
JOptionPane.showMessageDialog(null,"The soup of the day is Booty Chunks");
else if (day == "Saturday" || day == "Sunday")
JOptionPane.showMessageDialog(null, "Sorry we are closed", "Closed",
JOptionPane.ERROR_MESSAGE);
else
JOptionPane.showMessageDialog(null,"Be sure to check spelling and punctuation "
+ "such as capitals", "Sorry, not a day", JOptionPane.ERROR_MESSAGE);
}//end main
}
You're comparing the String literal with a reference.
Use day.equals("Monday") instead of day == "Monday"
This is a consequence of how Strings are implemented in Java, as it is comparing the hash code of the String literal in your code, which are not the same.
For instance, take two Strings:
String lol = "lol";
String lol2 = "lol";
System.out.println( (lol == lol2) ); // This prints "False"
System.out.println( lol.equals(lol2) ); // This prints "True"
When you directly compare any object (String, being a capital class is an object rather than a primitive like an int or float or char) with another object, it does not compare what is inside the object. Rather, it compares the hash code such that you are comparing two different references.
lol and lol2 may both print lol but just because they have the same contents does not mean that they are the same "containers" so to speak. This is relevant because your code uses a String literal which has its own hash code that Java must reference for comparison.
It is the .equals() method that allows Java to compare a String against a String, because doing so must be done in sequence, character by character. This is a result of the underlying C, and how C approaches Strings although there are fundamental differences between C and Java strings.
Comparing a string in C (char *), for instance, would only compare the value of the pointer to the first character to the pointer of the first character in the char * of the comparison. So the result for comparing char * lol and char * lol2 via == equivalence operators is essentially the same in C, with subtle differences (hash code, Object String in Java, etc.)
It's important to understand fully why this is the case, because it is essentially one of the cornerstone concepts in pass-by-reference object-oriented programming.
Ok with a little more research I found out that I had to use the equals method in the if parenthesis but I an unsure to why that is if anyone could help me understand that would be cool.
Related
What is technically wrong in this program? The expected result is 6 since that is the total number of words present in the string.
#include <iostream>
using namespace std;
int main()
{
string str = " Let's count the number of words ";
int word = 0;
for (int i = 0; str[i] != '\0';)
{
if ((str[i] == 32 && str[i + 1] == 32) || (str[i] == 32 && str[i - 1] == 32))
{
++i;
}
else if ((str[i] == 32 && str[i - 1] != 32) || (str[i] == 32 && str[i + 1] != 32))
{
word++;
}
++i;
}
cout << "No. of words: " << word << endl;
return 0;
}
My incorrect result:
No. of words: 0
Also, if I try changing the spaces in the string or even the string itself to a totally new set of spaced out words, say:
string str = " Hello world ";
string str = "Hello world! How are you? ";
I still get incorrect results, but different from 0. I'm new to C++ programming and these kinds of strange behaviors are giving me nightmares. Is this common? What I can do to get this corrected?
If you could highlight or correct my program the way I'd written it, it would be much helpful and quick for me to understand the mistake instead of having to know some new commands at this point. Because, as I said, I'm a total beginner in C/C++.
Thanks for your time!
I'm new to C++ programming and these kinds of strange behaviors are giving me nightmares. Is this common?
Yes, it's very common. You've written a load of logic piled up in a heap and you don't have the tools to understand how it behaves.
What I can do to get this corrected?
You can work on this from both directions:
debug this to improve your understanding of how it operates:
identify in advance what you expect it to do for some short input, at each line
single-step through it in the debugger to see what it actually does
think about why it doesn't do what you expected
Sometimes the problem is that your code doesn't implement your algorithm correctly, and sometimes the algorithm itself is broken, and often it's a bit of both. Working through both will give you some insight.
write code that is easier to understand in the first place (and equivalently, write algorithms that are easy to reason about).
This depends on you having some intuition about whether something is easy to reason about, which you develop from iterating step 1.
... instead of having to know some new commands at this point.
Well, you need to learn to use a debugger anyway, so now is as good a time to start as any.
We can certainly improve the existing code, although I'd prefer to fix the logic. In general I'd encourage you to abstract your existing if conditions out into little functions, but the problem is that they don't currently seem to make any sense.
So, how do we define a word?
Your code says it is at least one non-space character preceded or followed by a space. (Do definitely prefer ' ' to 32, by the way, and std::isspace is better than either.)
However your code's implied definition is problematic, because:
each word longer than one character has both a first and last character, and you'll count each of them
you can't check whether the first character is preceded by anything, without going out of bounds
the last character is followed by the null terminator, but you don't count that as whitespace
Let's just choose a different definition, that doesn't require reading str[i-1], and doesn't require the tricky traversal your current code gets wrong.
I claim that a word is a contiguous substring of non-whitespace characters, and words are separated by contiguous substrings of whitespace characters. So, instead of looking at each pair of consecutive characters, we can write pseudocode to work in those terms:
for (current = str.begin(); current != str.end(); ) {
// skip any leading whitespace
current = find_next_non_whitespace(str, current);
if (current != str.end()) {
// we found a word
++words;
current = find_next_whitespace(str, current);
}
}
NB. When I talked about abstracting your code out into little functions, I meant things like find_next_non_whitespace - they should be trivial to implement, easy to test, and have a name that tells you something.
When I said your existing conditions didn't seem to make sense, it's because replacing
if ((str[i] == 32 && str[i + 1] == 32) || (str[i] == 32 && str[i - 1] == 32))
with, say,
if (two_consecutive_spaces(str, i))
prompts more questions than it answers. Why have a special case for exactly two consecutive spaces? Is it different to just one space? What will actually happen if we have two words with a single space between them? Why do we advance by two characters in this case, but only one on the word branch?
The fact that the code can't easily be mapped back onto explicable logic is a bad sign - even if it worked (which we know it doesn't), we don't understand it well enough to ever change, extend or refactor it.
I think you have some ways to do it. Take a look at this code. Very similar to yours:
string s = " Let's count the number of words ";
int word = 0;
for (auto i = 0; s[i] != '\0'; i++) {
if (i == 0) {
if (s[i] != ' ') {
++word;
}
continue;
}
if (s[i - 1] == ' ' && s[i] != ' ') {
++word;
}
}
cout << "No of Words: " << word << endl;
The idea is to iterate over the string reading character by character. So we do some logic:
If we are in the first string character and it's equals to ' ', go to the next loop iteration
If we are in the first string character and it's different from ' ', means we are starting a word, so counts it and jump to the next loop iteration.
If we reach the second if, means we are not at the first position, so trying to access i - 1 should be valid. Then we just check if the previous char is a blank space and the current one it's not. This means we are starting a new word. So counts it and jump to the next loop iteration.
Another and more simple way to do it is using stringstream:
string s = " Let's count the number of words ";
stringstream ss(s);
string sub;
int word = 0;
while (ss >> sub) {
++word;
}
cout << "No of Words: " << word << endl;
This way you're basically extracting word by word from your string.
I am writing a simple program to check the grade of a person and output what Letter it is. For example I want to check if the user entered a number between 60-69 and if so out put a 'D'.
Any answers would be helpful, Thank you
If you want to ask user to enter something into the consol you need, first, say him what to do by using std::cout
After that you should get what he inserted into the consol by using std::cin.
After that you can compare the value with different condition to get the letter you want(the grade). A simple way can be like user "Beta" put on comments.
if(n < 60)
grade = "E";
else if(n >=60 && n <= 69)
grade = "D";
else if(....
...
Is it possible to write a one line if-else statement (i.e. only using one ;) without using the ?: expression? For instance something of the form:
if (p == 1) " " else "\n";
Potential purpose could be:
cout << if (p == 1) " " else "\n";
Just curious if this is possible, don't know if there are any practical applications for this.
Thanks
You're asking "how do I do X, without using any of the tools the language provides to do X". It's silly.
And the answer's no. It's not possible.
This doesn't address the general question, but it does work for the specific example you provided.
std::cout << " \n"[(bool)(p - 1)];
Explanation:
First, a string literal (such as " \n") is an array. As such, it participates in pointer decay, and can be indexed just like any other pointer or array.
Second, an integer can be converted to a bool, and the conversion has the special property that a zero is converted to false, and anything else is converted to true. So when I subtract 1 from p, then convert it to bool, it is false if p is 1, and true otherwise.
Third, a bool can be (implicitly) converted back to an integer. false converts to 0, and true converts to 1. So converting from an int to a bool and back has the result that a 0 stays a 0, and anything else becomes a 1.
So, with those three points taken into consideration, the expression:
" \n"[(bool)(p - 1)]
results in one of these two possibilities:
" \n"[0] // a space (if p == 1)
" \n"[1] // or a newline (if p != 1)
I'd downvote this answer if I could.
You already used the two important words that are key to undestand why what you intend is not possible, but you probably haven't grasped their full meaning: Statement and expression.
The if statement (like all statements) does not yield a value, while the ?: operator is an expression that does yield a value.
Distinguishing between statements and expressions is a fundamental concept that is worth learning (check out the links in this answer and take your time!), not just for C++ but for almost all programming languages.
cout << [=]{ if (p == 1) return " "; else return "\n"; }();
Basically: no, it's not possible to do this:
cout << if (p == 1) " " else "\n";
That is exactly the purpose of ?: operator - it yields value. Some things may not be possible with if-else syntax. Example: conditional initialization. Consider:
if(p == 1)
int value = 1; //local variable!
else
int value = 0; //and so is this one!
//here 'value' is unknown
Above problem could be solved this way:
int value; //default initialization
if(p == 1)
value = 1; //assignment to already initialized variable!
else
value = 0; //and so is this!
But these two are not equal. For some types, it may result in totally different behavior, because initialization is different from assignment. ?: is a solution:
int value == (p == 1) ? 1 : 0; //'value' is initialized with value, that depends on 'p'
Do not try to do things without tools, that were designed to do that things for you.
I seem to be running into an issue. While trying to get input based off of A.M./P.M. entry,my if else statement is having some sort of logic error. I've never really done this sort of thing (I'm a bit new to c++) so help would be appreciated.
cout << "What time was the dose administered? (Round to hour): ";
cin >> time;
cout << "A.M./P.M.? ";
cin >> ap;
cout << ap;
if (ap == "A.M.", "am"){
ap = "A.M.";
}
else if (ap == "P.M.", "pm"){
ap = "P.M.";
}
else { cout << "This is not a valid entry.";
}
"ap" is a string.
No matter what is entered, the result is "A.M."
Side note: Originally, it would only print "P.M." but both statements were orignally "if", when I changed it to "if else" it began printing "A.M." only.
This...
ap == "A.M.", "am"
...under the rules of operator precedence, is equivalent to...
"am"
...which in a boolean context undergoes standard conversion to true (via a non-0 pointer).
That's because the comma operator evaluates the sub-expression on its left - namely ap == "A.M." - and while any side-effects of that evaluation are enacted the actual value of the sub-expression is then discarded and the sub-expression on the right - namely "am" - is evaluated and used instead.
You should instead use:
if (ap == "A.M." || ap == "am")
(The C++ Standard allows the keyword "or" as an alternative to ||, but famously Microsoft's compiler doesn't support it without an extra command-line argument, so in practice it's best avoided for portable code.)
I thought I would try and write some encryption program that converts input to numbers in a file.
I made a table, giving each letter its own number. The code itself went a little like this for each letter:
if (Letter = "P")
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
It came up with "cannot convert from 'const char [2]' to 'char'"
Can anyone suggest how I would go about actually getting a number from a letter?
If Letter is a char, use a char literal:
if (Letter == 'P')
...
Your conditional checking is wrong. It should be ==, not =. A single = means assignment whereas a == means conditional checking.
I am assuming Letter is a character array. In that case, you can use strcmp to compare it with P.
if(strcmp(Letter, "P") == 0)
{
// rest of the code
}
Take a look at the strcmp function reference here, if necessary.
If Letter is simply a char, then you need to compare it with P like this -
if(Letter == 'P')
{
// rest of the code
}
A single quote around a character makes it a character literal, which then can be compared against another character using ==.
You can not compare C++ char to C++ string! You should use single quote for chars, not double quotes. Also, the C++ equals operator is not =, it is ==. the single = is the assignment operator.
You should write the condition like this :
if (Letter == 'P')
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
(Letter = "P")
This is an assignment, not comparison.
You probably meant (Letter == "P") which would also be wrong, you need strcmp.
you need to use strcmp to compare....as = is an assignment operator....
I would recommend that when you give us an error message as you did, you give us the full message - including line numbers so that we know where the error occurred (or tell us what line it occurred at). Paying attention to those line numbers can greatly help finding the true problem.
Given the error message I'm assuming Letter is of type char - you need to understand the difference between literal strings (enclosed in double quotes) and literal characters (enclosed in single quotes).
As Luchian also mentioned, you have an assignment rather than an equality test - unlike Visual Basic, if that is where you're coming from, the two have different symbols.
That should thus be:
if (Letter == 'P')