Error: Expected a Statement / C++ / Visual Studio - c++

As I plan to make a small game to test myself on what I know so far in C++, I found that using this is giving me an error at the location of the "else".
Can anyone help?
int lvlup()
{
if (user.xp >= user.maxxp)
user.xp = 0;
user.maxxp + 10;
user.maxhealth += user.maxhealth * .5;
user.defense + 2;
user.attack + 3;
user.lvl + 1;
else
return 0;
};

You need to group statements with {} in c++, and you don't need a ; after the function.
You also have missed the = sign in a few places. I'm assuming user is a global, but it really should be passed in, but I'll leave that up to you.
I'm assuming the return value is whether the user leveled up, so that really should be a bool, not an int. I've added a return statement to the if true block. Depending on the use of lvlup that may or may not make sense. If the return value is not used you shouldn't have any and use void.
So your code should be:
int lvlup()
{
if (user.xp >= user.maxxp)
{
user.xp = 0;
user.maxxp += 10;
user.maxhealth += user.maxhealth * .5;
user.defense += 2;
user.attack += 3;
user.lvl += 1;
return 1;
}
else
return 0;
}
If your if/else statement has only one line you can choose not to have any braces, but if there is more than one line to be executed in response to the conditional you need to include them. However not including them can open up the possibility for someone maintaining the code to make a mistake and not put them in when adding a line to the block, so some people say always add them.

You need some brackets {}.
In fact, the if brunch and the for loop only execute the next line if no brackets found surrounding the piece of code.
example :
a = 1;
if (a == 0)
std::cout << "This line is skipped" << endl;
std::cout << "This line will appear" << endl;
If you execute this code, the output will be:
This line will appear
and if an else is following the if statement, a compilation error is generated which is your case :p
and if you write down some brackets to structure your code like below:
a = 0;
if (a == 0) {
std::cout << "This line is not skipped" << endl;
std::cout << "This line will appear too" << endl;
}
the output will be :
This line is not skipped
This line will appear too
The for loop will only loop the only line next to the for loop if no brackets found too.

Related

Cannot understand error: "warning: control reaches end of non-void function [-Wreturn-type]"

I have been learning c++ recently. When I tried to run the following lines...
#include <iostream>
short a = 0;
short b = 1;
short c, i;
void Fibonacci(){
std::cout << a;
std::cout << b;
while (a <= 100){
c = a + b;
a = b;
b = c;
std::cout << c;
}
}
int prime_number(short a){
if (a == 1){
std::cout << "It's a prime number\n";
} else{
for (i = 2; i < a; i++){
if ((a%i) == 0){
std::cout << "It's a prime number\n";
std::cout << "The given number is divisible by " << i << "\n";
return 0;
}
}
std::cout << "It's not an prime number";
}
}
int main(){
short user_input;
std::cout << "Press 1 for Fibonacci and 2 for prime number";
std::cin >> user_input;
if (user_input == 1){
Fibonacci();
}
if (user_input == 2){
std::cout << "Type the number to check whether it's prime";
std::cin >> a ;
prime_number(a);
}
}
...I get an error saying:
In function ‘int prime_number(short int)’:
Function.cpp:37:1: warning: control reaches end of non-void function [-Wreturn-type]
37 | }
I searched various platforms for the answers, but I couldn't understand what really happens here. It's an error because the compiler cannot find whether the function has an end or not. Can someone help me understand the error and solve it?
Warnings aren't errors. When you compile a program and only get warnings (ie. no errors) then this means your program has successfully compiled (an executable has been made). When you get errors, this means that compilation was aborted (so no executable output - if you already had one, it won't have been updated).
It's warning you that when the integer input is 1 that you aren't specifying a return — which is invalid. Also, if it's not 1, then the the else statement still doesn't guarantee a returned value:
for (i = 2; i < a; i++){
if ((a%i) == 0){
std::cout << "it's a prime number\n";
std::cout << "The given number is divisible by " << i << "\n";
return 0;
}
}
The compiler can't know that return 0 will always be executed here - and even if it could, the compiler isn't designed to always understand the logic of your code. Even knowing your logic, return 0 will only be executed if a is greater than 2 and non-prime.
You could fix this by putting return statements in both of your if statements, or even at the end of your function. But notice that you never use the return value? This implies that your prime_number() function should be void prime_number(), then you won't need return values at all, and can just use break; in your loop - or return; if you prefer (here's an example of how to resolve this particular issue - there's still other bugs though, discussed below).
This is probably confusing to a beginner: Why doesn't it warn you when the function int main() contains no return value? This is because main is special: If no return value is given, it implies return 0.
Another thing that may confuse you here is if you ever compile with the flag -Werror. If you do, then the original code will give you an error, because the Werror flag turns all warnings into errors (to force programmers to pay attention to the warnings).
The logic of your code isn't right - it's actually the opposite: 1 is defined as not a prime number (this is because of the value we get from unique prime decomposition, so mathematicians chose to exclude 1 as prime). Also, ((a%i) == 0) means that when a is divided by i that it has 0 remainder, ie. i divides a, so a is not prime.
Finally, avoid using global variables. Keep all your variables local so that the logic of your code is simpler (easier to read / less bug-prone).
Here's an example of how you could rewrite your code that resolves all the above issues.
As Elliott in the comments has said the warning you are getting is not going to affect your program at all. It's recommend that you return something since you function has a return type of integer.
Below is a easy fix to get rid of the warning. :)
Old Code:
if (a == 1)
{
std::cout << "Its a prime number\n";
}
New Code without the Warning:
if (a == 1)
{
std::cout << "Its a prime number\n";
return 0;
}

Simple program, cannot get for loop to execute

Brand new programmer, so green behind the ears that I could be a frog. The intent of this program is to use a for loop (not a simple formula) to add all integers up to a user designated value. It executes all code up to the for loop perfectly, however the for loop does not seem to run. Here is the code in question:
#include "stdafx.h"
#include <iostream>
int main(int num=0)
{
int sum = 0;
std::cout << "This program will sum all integers up to a given value";
std::cout << std::endl << std::endl;
std::cout << "Please enter a number "<<std::endl;
std::cin >> num;
std::cout << std::endl << "You've chosen the number " << num<<std::endl;
for (int i = 1; i <= num; ++i)
sum += i;
return (sum);
std::cout << "The sum of all numbers up to " << num << " is " << sum;
}
Any help is appreciated!
When it meets return for the first time, the program will be end.
Please put the return at the end of main function.
One more thing, shouldn't use parameter num in main function.
Write a separately function sum_all_integers and then call it in main function.
Good news: your code works! The issue is that when return (sum); is called, the function is exited, and the line that would print out your answer is not executed.
I would also recommend adding the using namespace std; line after your includes, so that you don't end up with so much std:: pollution. Also main should not take any arguments, so put that int num=0 line inside the main block.
Oh, you should also be aware of your return line indentation.
In this section
for (int i = 1; i <= num; ++i)
sum += i;
return (sum);
Your program will exit.
This boils down to what other answers have mentioned: return from main means exiting the program. Keep in mind that is is true even from within a loop like while or for - doing so is how one might design a search function which exits as soon as it has a result, for example.
To exit a for loop prematurely, use break. To continue to the next iteration and skip further code in the loop, use continue.
Also note that the indentation of return is misleading - it will be executed after the for loop, since the lack of brackets ({}) will make for only loop through the next line, which is sum += i; Keep in mind that C++ is not a whitespace sensitive language, so indentation means nothing to the logic (I like to abuse this in large blocks of similar code by tab-aligning). This is also a good example of why it is common practice to use brackets even when not strictly necessary. EDIT See also Apple's infamous "goto fail" bug.
You return the sum right after the loop:
for (int i = 1; i <= num; ++i)
sum += i;
return (sum);
This means, you sum up the numbers and then exit the program before you print the result.

Using curly braces to separate code in C++

One thing I really like about IDEs is the ability to "minimize" sections of code, so that:
while(conditions){
// Really long code...
}
Can become:
while(conditions){ // The rest is hidden
My question is whether or not something like this would be acceptable formatting
// Code
{
// More code
}
// Code
I understand that anything done inside the brackets would have that limited scope, but I can also edit variables in the outer scope as well.
So, for a short, unnecessary example
int x = 1;
{ // Create new variable, add and output
int y = 2;
cout << x + y;
}
Would become:
int x = 1;
{ // Create new variable, add and output (The rest of the code is hidden)
So would this be acceptable, or shunned?
Here is a real example of something I would want to just hide.
/// Add line to msg vector
// Check to see if each side X is needed
if(uniqueSide && line == 1){
// Create stringstream to hold string and int (e.g. "Message " + 1 + " - Side " + 1
stringstream tempString;
// Add full line to stringstream. validMessages.length() + 1 will make Message X be incremental
tempString << "Message " << (validMessages.length() + 1) << " - Side " << numSide;
// Then append full string (e.g. "Message 1 - Side 1") to msg
msg.append(tempString.str());
}
// Else just add Message X using same method as above
else if(line == 1){
stringstream tempString;
tempString << "Message " << (validMessages.length() + 1);
}
// Add each line to msg vector with double space indent and (width) before each line
stringstream tempString;
tempString << setprecision(5) // Makes width be output as 10.325 or 100.33
<< " (" << width << ") " << tempInput
msg.append(tempString.str());
Thanks.
At least in my opinion, if you need (or even want) this very much, you're probably not structuring your code very well.
An interest in hiding code tends to indicate that you may have too much code shoved together that might be better off being separated into more meaningful functions or (usually even better) generic algorithms.
I'd like to go into more detail and give more specific advice about how some code could be improved, but it's hard to do that when the question is so general, and the little code it contains lacks any context, so it's almost impossible to guess what it represents, which is the first thing you need to do to improve it much.
That said: I'd say as a general rule, adding a block without it being controlled by an flow control statement is perfectly reasonable -- but it's usually done to control object lifetimes -- if you want something created and destroyed, use an RAII object and put it in a block, so when execution exits the block, it'll be destroyed automatically.
Edit: At least to me, your sample looks ripe (overdue?) for some serious refactoring.
/// Add line to msg vector
// Check to see if each side X is needed
if(uniqueSide && line == 1){
// Create stringstream to hold string and int (e.g. "Message " + 1 + " - Side " + 1
stringstream tempString;
// Add full line to stringstream. validMessages.length() + 1 will make Message X be incremental
tempString << "Message " << (validMessages.length() + 1) << " - Side " << numSide;
// Then append full string (e.g. "Message 1 - Side 1") to msg
msg.append(tempString.str());
}
// Else just add Message X using same method as above
else if(line == 1){
stringstream tempString;
tempString << "Message " << (validMessages.length() + 1);
}
Right now, your else clause isn't really doing anything (puts something in tempString, but that's local, so it disappears upon exit from the block. Let's assume the comment is correct, so the else should have:
msg.append(tempString.str());
before it exits. In this case, the two legs of the code are similar enough that they should probably be (mostly) merged:
stringstream tempString;
tempString << Message << validMesssages.length()+1;
if (uniqueSide && line == 1)
tempString << " - Side " << numSide;
msg.append(tempString.str());
Then, since the last part of that is executed unconditionally, we can merge the rest of the code with the preceding (and in the process, eliminate quite a bit so we end up with something like this:
stringstream tempString;
if (line == 1) {
tempString << "Message " << validMesssages.length()+1;
if (uniqueSide) tempString << " - Side " << numSide;
}
tempString << setprecision(5) << " ( " << width << " ) " << tempInput;
msg.append(tempString.str());
From there, the question is whether it makes sense to turn that into a function or functor, so the calling code would end up something like:
msg.append(msg(line, validMessages, uniqueSide, numSide, width, tempInput));
Whether you want to do that, only you can probably say. Personally, I think it would depend on whether you were writing similar code in a number of places. If this is the only place with code like that, I'd probably leave it, but if you need the same code in two (or more) places, a function starts to make a lot more sense.

C++ For Loop not Exiting

I have a for loop, a very simple one, in my program, and I want it to loop through and do something for some minimum number of times. However, the loop simply...stops. But does not move on to the next thing in the program. For instance, when min is 9, it runs for i=0 to i=8, then freezes. It should exit the for loop, but it does not execute the next print instruction, nor does it execute the loop again. It just stops. The program hangs, doing absolutely nothing as far as I can tell. I don't understand why this is.
The merged.put() function I want to execute just puts x or y in merged, depending on the condition. That part works. This is just a small part of a much larger program. sp1, sp2, and merged are all defined elsewhere.
int i;
int x;
int y;
for(i=0; i < min; i++)
{
cout << " here " + convert(i);
x = sp1.get_num(i);
y = sp2.get_num(i);
if(x >= y) {
merged.put(x);
}
else {
merged.put(y);
}
cout << " end" << endl;
}
cout << "out";
EDIT: I'm not posting the entire code, it's several hundred lines long. Type of min is int. The reply down there was helpful, when << endl was added to the last print statement, it printed. My problem now appears to be here, getting stuck on the second while, because I was not incrementing i. Shame on me...thanks for the help. (This comes directly after the above code)
if (sp_large == 2) {
cout << "1" << endl;;
while (i < sp2.get_size()) {
merged.put(sp2.get_num(i));
}
}
else {
while (i < sp1.get_size()) {
merged.put(sp1.get_num(i));
}
cout << "2" << endl;
}
EDIT: Problem solved, thanks for the help.
I'm betting that it's actually a later part of the program that is hanging.
This line:
cout << "out";
just puts "out" on the output-buffer, and won't actually print "out" until the output-buffer gets flushed. (Which could happen immediately, but is not likely to.) Change that line to this:
cout << "out" << endl;
and "out" will be printed as soon as that line is run. This will help you figure out if the program is hanging before it gets to that line, or somewhere later on.

A CPP int to string in a statement question

I have to write something like
q.push_back(q1); ... to ... q.push_back(q100);
I am writing this as
for (int i = 1; i <= 100; i++) {
try {
std::string s = boost::lexical_cast<std::string > (i);
"q.push_back(q" + s + ");";
} catch (boost::bad_lexical_cast &) {
std::cout << "Some error message \n";
}
}
It compiles (no syntax errors) but does not work. I don't know how to mix cpp statements and strings to make a compound statement.
Any help here would be highly appreciated. Thanks!
How about:
for (int i = 1; i <= 100; i++)
{
std::cout << "q.push_back(q" << i << ");\n";
}
If you're using std::string (which it looks like you are) try s.append(str);
std::ostringstream os;
for( int i = 1; i < 100; ++i)
{
os << "s.push_back( q" << i << "); ";
}
std::string result = os.str();
// Do what you need with result
Your output string was put inside the for loop, so at each loop the string is initialized, the content generated in the previous loop was lost.
You aren't telling it where to put that string, it just creates a temporary. Try appending to s.
std::string s = "q.push_back(q";
s.append(boost::lexical_cast<std::string > (i));
s.append(");");
It isn't clear what you expect to do with the string. If you are printing it to std::cout, then your error message will get mixed in with the results. You should use std::cerr instead.
std::cerr << "Some error message" << std::endl;
The variables q1, q2, ..., q100 should have been an array in the first place.
If my understanding of what you are trying to do is correct, then you basically want to automatically generate some code. For that, people normally use simple macro definitions...
You can just define a macro that takes your respective integer from the for loop as a parameter and expands to the code you require with it...
Take a quick look at [ http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation ]. You can use ## in macros to glue things together, so you could use something like the following, inside a for loop for i:
#define MY_PUSH(vector, i) vector.push_back(q##i);
But as people have suggested, it might have been better to use an array of variables in the first place, as macros are basically evil for anything other than raw code generation tools...