-2

i have just made a c++ program to calculate average based on numbers the user enters but it always gives wrong answers though it is simple and small i cant discover what is wrong:

#include <iostream>

using namespace std;

void average(void);
char input = 0;
int number = 0;
int mode = 0;
int sum = 0;

int main()
{
    cout << "This is a program to calculate the average(mean) of numbers you write. \nPlease enter all the numbers you want to calculate. \nWrite \'q\' after entering numbers to calculate! ^_^" << endl;
    average();
    return 0;
}

void average(void){

    while(input != 'q'){
        cin >> input;
        sum += input;
        number++;

    }

    mode = (sum / number);
    cout << "\aThe mode= " << mode;
}

EDIT


an example of wrong results i always get: https://i.stack.imgur.com/5mhdI.png

ilouy
  • 1
  • 1
  • 8
  • 4
    Since you're using a `char` variable, you're averaging the ASCII code for each input character, not averaging the numbers that they type. – Barmar Jan 19 '15 at 11:40
  • You have to convert "input" from char to int: http://stackoverflow.com/questions/5029840/convert-char-to-int-in-c-and-c – vincentp Jan 19 '15 at 11:40
  • 1 sec i ll post what i get in edit – ilouy Jan 19 '15 at 11:42
  • @vincentp i need it char to see if user inputted letter q int wont work in this case and sum must be int because sum may be more than 255 what u think i should do – ilouy Jan 19 '15 at 11:47
  • You need something like "sum += charToInt(input);". – vincentp Jan 19 '15 at 11:50

4 Answers4

1

There are a number of issues with your code: the most obvious is that you are using the results of input without first checking whether the input succeeded, and that you're using the character encoding as an integral value.

The most idiomatic way of writing this would be something like:

int input;
while ( std::cin >> input ) {
    sum += input;
}

This isn't perfect; if the use inputs a letter, then this treats it as end of file. A possibly more robust solution would be:

std::string line;
while ( std::getline( std::cin, line ) ) {
    std::istringstream parse( line );
    int input;
    if ( parse >> input >> std::ws && parse.get() == EOF ) {
        sum += input;
    } else {
        std::cerr << "not a number: " << line << std::endl;
    }
}

This assumes (requires) one number per line, which is a simple format, and easy to verify and to resynchronize in case of error. If line endings are without meaning, resynchronizing becomes more complex.

Both of these solutions input until end of file, which is the most nature solution (rather than looking for a q). If you insist on ending with a specific token, and the input is line oriented, you can do something like:

std::string line;
while ( std::getline( std::cin, line ) && notEndToken( line) ) {
    //  ...
}

with the same loop body as above. The function notEndToken could be as simple as return line == "q";, but more likely, you'll want to skip spaces, allow upper and lower case, etc., so it makes more sense to put it into a separate function. (Of course, you still need to check that the input has succeeded. Just because you're expecting a special token doesn't mean that you'll get one. You have to handle end of file correctly in every case.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
0

You are adding char values from the input to your sum. If I type '2', the UTF-8 or ASCII value of the char will be 50. You would then add 50 to the sum. Basically you are doing it wrong.

What you need to do is either acquire int values (input must be int) OR if you want to keep checking for "q', you have to convert the textual values (input as char or string) into int values before adding it to the sum. There are several ways to do this depending on your C++ version and if you yave access to Boost.

Maybe using a string as input will fix other problems as your code (once fixed with char) will not work with bigger numbers than 9.


Here is a version that works for me (C++11 and slight improvements):

#include <iostream>
#include <string>

using namespace std;

void average();

int main()
{
    cout << "This is a program to calculate the average(mean) of numbers you write. \nPlease enter all the numbers you want to calculate. \nWrite \'q\' after entering numbers to calculate! ^_^" << endl;
    average();
    return 0;
}

void average() {
    std::string input;
    int number = 0;
    int sum = 0;

    cin >> input;
    while (input != "q") {
        sum += std::stoi(input);
        number++;
        cin >> input;
    }

    const int mode = (sum / number);
    cout << "\aThe mode= " << mode;
}

Note that I slightly changed the order of execution of the while loop because it was incorrectly running one last cycle when you entered 'q'. Also, this version will throw an exception if the entry is not a number (which is ok I guess here). Finally, note that if you are using C++03, then you can use std::atoi(input.c_str()) instead of std::stoi(input). I also improved a bit the variable usage. You definitely don't need to put everything global.

But this example is designed around your original code which is problematic to begin with, at least for checking for errors. So this is not ideal, as pointed in comments, and a more idiomatic input-checking way is also provided in James Kanz's answer (+1). Ideally you should prefer his version, here it's just to show you a direct example from your case.

Klaim
  • 67,274
  • 36
  • 133
  • 188
  • @ilouy Don't forget to vote and select my answer ;) I don't know why someone voted down. – Klaim Jan 19 '15 at 11:52
  • can i use sum += (int)input; ? – ilouy Jan 19 '15 at 11:52
  • @ilou You can't just cast the value, it will only keep the same result. You better make input a std::string (include ) then use std::atoi() function. That way your program will work with numbers bigger than 9 too. – Klaim Jan 19 '15 at 11:53
  • @ilou I added a complete example using a string. Another note: your code could be fastly simplified if you put the variables you need close to where they are used. – Klaim Jan 19 '15 at 12:07
  • This code is simply wrong. It uses the result of input without checking that the input succeeded. And af you're going to use `std::stoi`, then you'll need to catch exceptions. You really don't want the program to crash if the user inputs `"a"`. – James Kanze Jan 19 '15 at 12:16
  • @Klaim Why someone voted it down? Probably because the code isn't correct. – James Kanze Jan 19 '15 at 12:17
  • @JamesKanze That's the dev choice to catch or not the exception or use something else like boost.lexical_cast with default value to not throw exception. This is an example that work with valid inputs. The choice of how to manage wrong input is not mine to do. Also the downvote appeared before I added the example. I could make another example but no time. – Klaim Jan 19 '15 at 12:37
  • @Klaim A program which crashes, regardless of the input, is incorrect. A program which uses the value from an input without checking that the input succeeded is incorrect. (And with regards to `atoi`: there's no way to use this function correctly, since it doesn't provide adequate error checking.) – James Kanze Jan 19 '15 at 13:43
  • @JamesKanze Ideally yes. I'm upvoting your answer and adding a note here. Keep in mind that I tried to fix directly the actual mean calculus error, not the whole program. – Klaim Jan 19 '15 at 14:47
0

after research:

#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>

using namespace std;

void average(void);
string input;
int number = 0;
int mode = 0;
int sum = 0;
int StringToNumber ( const string& );

int main()
{
    cout << "This is a program to calculate the average(mean) of numbers you write. \nPlease enter all the numbers you want to calculate. \nWrite \'q\' after entering numbers to calculate! ^_^" << endl;
    average();
    return 0;
}

int StringToNumber ( const string& Text )
{
    stringstream ss(Text);
    int result;
    return ss >> result ? result : 0;
}

void average(void){

    cin >> input;
    while (input != "q") {
        sum += StringToNumber(input);
        number++;
        cin >> input;
    }

    mode = (sum / number);
    cout << "\aThe mode= " << mode;
}
ilouy
  • 1
  • 1
  • 8
-1

The problem with the code is, you have taken input as a char. What is happening here is that, cin is reading a character value in the variable.

For example, when you input 123, it only reads 1 and treats it as a character, and stores its ASCII value, which is 49 in the input variable. Which means, you are adding 49 into sum, instead of 123. That is why you are getting a wrong answer.

You should change char input = 0; to int input = 0; and change your terminating condition to something else.

zahirdhada
  • 405
  • 4
  • 14