Ignoring invalid input from a count and average












1














The program requires the user to input numbers and when finished to exit the loop by entering a negative number. The program will then output the average of the numbers and the count of the numbers. The negative number should be removed from the series though. So if we have three numbers and exit on the (fourth) negative number, the average will only be of the three numbers and not include the negative number. Neat, I somehow made that work. Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100 also using a Boolean equation. It is at this point that I cannot determine how to exclude the erroneous input from the results.



#include <iostream>
#include <iomanip>

using namespace std;

int main ()
{
float inScore= 1;
float sumScore= 0.0;
int scoreCount= 0;
float avgScore= 0.0;
bool moreNumbers = true;
bool notNumbers = true;


for ( inScore =1; inScore >=1; inScore++) //for loop some kind of blackmagic not really sure about this right now
{
cout << "Please enter grades (enter a negative integer to exit): ";
cin >> inScore;
if (!cin || inScore > 100)
{
notNumbers = false; //boolean to ignore non integers or numbers greater than 100
cin.clear();
cin.ignore(256, 'n');
scoreCount--;
cout << "Invalid number!" << endl;
} //something is wrong in this section and I can't get it to ignore the invalid inputs

else if (inScore < 0)
{
moreNumbers = false;
} //breaks the loop upon a negative number being entered
else
sumScore+=inScore;
scoreCount++;
}
avgScore = (sumScore+=inScore)/(scoreCount-1);
cout << "Number of Grades: " << scoreCount-1 << endl; //number of entries
cout << "Average: " << avgScore << endl; // average grade except I cannot figure out how to remove negative number from the array

return 0;
}









share|improve this question
























  • Don't you need specify n? istream& ignore (streamsize n = 1, int delim = EOF);
    – Soumya Kanti
    Nov 12 '18 at 3:55










  • I see the comment after for ( inScore =1; inScore >=1; inScore++), but if you're going to use junk code as a place holder, try to use something that makes sense. This only serves to obscure your problem.
    – user4581301
    Nov 12 '18 at 4:16










  • Suggestion: Don't BS code, write less code. Right now what you want to figure out is how to get a valid number and only a valid number. To do that, write a function that does exactly that and nothing else. Then write a simple main function that tests the function every way you can think of. Once you have the function working, worry about looping calls to the function until you hit the exit condition. Think small and then bolt the small things together into something big.
    – user4581301
    Nov 12 '18 at 4:17










  • Totally unrelated. But to get back on topic, cin.ignore(); removes only one character. You need to remove the whole bad input and probably the whole line. To do that you'll want cin.ignore(numeric_limits<streamsize>::max(), 'n') and #include <limits> to get max.
    – user4581301
    Nov 12 '18 at 4:21










  • I changed the cin.ignore to reflect the size of the input and added "scoreCount--;" to remove the erroneous input. It seems to give the intended results at this point. Thanks @user4581301
    – Chris Wagner
    Nov 12 '18 at 4:39
















1














The program requires the user to input numbers and when finished to exit the loop by entering a negative number. The program will then output the average of the numbers and the count of the numbers. The negative number should be removed from the series though. So if we have three numbers and exit on the (fourth) negative number, the average will only be of the three numbers and not include the negative number. Neat, I somehow made that work. Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100 also using a Boolean equation. It is at this point that I cannot determine how to exclude the erroneous input from the results.



#include <iostream>
#include <iomanip>

using namespace std;

int main ()
{
float inScore= 1;
float sumScore= 0.0;
int scoreCount= 0;
float avgScore= 0.0;
bool moreNumbers = true;
bool notNumbers = true;


for ( inScore =1; inScore >=1; inScore++) //for loop some kind of blackmagic not really sure about this right now
{
cout << "Please enter grades (enter a negative integer to exit): ";
cin >> inScore;
if (!cin || inScore > 100)
{
notNumbers = false; //boolean to ignore non integers or numbers greater than 100
cin.clear();
cin.ignore(256, 'n');
scoreCount--;
cout << "Invalid number!" << endl;
} //something is wrong in this section and I can't get it to ignore the invalid inputs

else if (inScore < 0)
{
moreNumbers = false;
} //breaks the loop upon a negative number being entered
else
sumScore+=inScore;
scoreCount++;
}
avgScore = (sumScore+=inScore)/(scoreCount-1);
cout << "Number of Grades: " << scoreCount-1 << endl; //number of entries
cout << "Average: " << avgScore << endl; // average grade except I cannot figure out how to remove negative number from the array

return 0;
}









share|improve this question
























  • Don't you need specify n? istream& ignore (streamsize n = 1, int delim = EOF);
    – Soumya Kanti
    Nov 12 '18 at 3:55










  • I see the comment after for ( inScore =1; inScore >=1; inScore++), but if you're going to use junk code as a place holder, try to use something that makes sense. This only serves to obscure your problem.
    – user4581301
    Nov 12 '18 at 4:16










  • Suggestion: Don't BS code, write less code. Right now what you want to figure out is how to get a valid number and only a valid number. To do that, write a function that does exactly that and nothing else. Then write a simple main function that tests the function every way you can think of. Once you have the function working, worry about looping calls to the function until you hit the exit condition. Think small and then bolt the small things together into something big.
    – user4581301
    Nov 12 '18 at 4:17










  • Totally unrelated. But to get back on topic, cin.ignore(); removes only one character. You need to remove the whole bad input and probably the whole line. To do that you'll want cin.ignore(numeric_limits<streamsize>::max(), 'n') and #include <limits> to get max.
    – user4581301
    Nov 12 '18 at 4:21










  • I changed the cin.ignore to reflect the size of the input and added "scoreCount--;" to remove the erroneous input. It seems to give the intended results at this point. Thanks @user4581301
    – Chris Wagner
    Nov 12 '18 at 4:39














1












1








1







The program requires the user to input numbers and when finished to exit the loop by entering a negative number. The program will then output the average of the numbers and the count of the numbers. The negative number should be removed from the series though. So if we have three numbers and exit on the (fourth) negative number, the average will only be of the three numbers and not include the negative number. Neat, I somehow made that work. Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100 also using a Boolean equation. It is at this point that I cannot determine how to exclude the erroneous input from the results.



#include <iostream>
#include <iomanip>

using namespace std;

int main ()
{
float inScore= 1;
float sumScore= 0.0;
int scoreCount= 0;
float avgScore= 0.0;
bool moreNumbers = true;
bool notNumbers = true;


for ( inScore =1; inScore >=1; inScore++) //for loop some kind of blackmagic not really sure about this right now
{
cout << "Please enter grades (enter a negative integer to exit): ";
cin >> inScore;
if (!cin || inScore > 100)
{
notNumbers = false; //boolean to ignore non integers or numbers greater than 100
cin.clear();
cin.ignore(256, 'n');
scoreCount--;
cout << "Invalid number!" << endl;
} //something is wrong in this section and I can't get it to ignore the invalid inputs

else if (inScore < 0)
{
moreNumbers = false;
} //breaks the loop upon a negative number being entered
else
sumScore+=inScore;
scoreCount++;
}
avgScore = (sumScore+=inScore)/(scoreCount-1);
cout << "Number of Grades: " << scoreCount-1 << endl; //number of entries
cout << "Average: " << avgScore << endl; // average grade except I cannot figure out how to remove negative number from the array

return 0;
}









share|improve this question















The program requires the user to input numbers and when finished to exit the loop by entering a negative number. The program will then output the average of the numbers and the count of the numbers. The negative number should be removed from the series though. So if we have three numbers and exit on the (fourth) negative number, the average will only be of the three numbers and not include the negative number. Neat, I somehow made that work. Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100 also using a Boolean equation. It is at this point that I cannot determine how to exclude the erroneous input from the results.



#include <iostream>
#include <iomanip>

using namespace std;

int main ()
{
float inScore= 1;
float sumScore= 0.0;
int scoreCount= 0;
float avgScore= 0.0;
bool moreNumbers = true;
bool notNumbers = true;


for ( inScore =1; inScore >=1; inScore++) //for loop some kind of blackmagic not really sure about this right now
{
cout << "Please enter grades (enter a negative integer to exit): ";
cin >> inScore;
if (!cin || inScore > 100)
{
notNumbers = false; //boolean to ignore non integers or numbers greater than 100
cin.clear();
cin.ignore(256, 'n');
scoreCount--;
cout << "Invalid number!" << endl;
} //something is wrong in this section and I can't get it to ignore the invalid inputs

else if (inScore < 0)
{
moreNumbers = false;
} //breaks the loop upon a negative number being entered
else
sumScore+=inScore;
scoreCount++;
}
avgScore = (sumScore+=inScore)/(scoreCount-1);
cout << "Number of Grades: " << scoreCount-1 << endl; //number of entries
cout << "Average: " << avgScore << endl; // average grade except I cannot figure out how to remove negative number from the array

return 0;
}






c++ loops boolean






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 4:37

























asked Nov 12 '18 at 3:46









Chris Wagner

64




64












  • Don't you need specify n? istream& ignore (streamsize n = 1, int delim = EOF);
    – Soumya Kanti
    Nov 12 '18 at 3:55










  • I see the comment after for ( inScore =1; inScore >=1; inScore++), but if you're going to use junk code as a place holder, try to use something that makes sense. This only serves to obscure your problem.
    – user4581301
    Nov 12 '18 at 4:16










  • Suggestion: Don't BS code, write less code. Right now what you want to figure out is how to get a valid number and only a valid number. To do that, write a function that does exactly that and nothing else. Then write a simple main function that tests the function every way you can think of. Once you have the function working, worry about looping calls to the function until you hit the exit condition. Think small and then bolt the small things together into something big.
    – user4581301
    Nov 12 '18 at 4:17










  • Totally unrelated. But to get back on topic, cin.ignore(); removes only one character. You need to remove the whole bad input and probably the whole line. To do that you'll want cin.ignore(numeric_limits<streamsize>::max(), 'n') and #include <limits> to get max.
    – user4581301
    Nov 12 '18 at 4:21










  • I changed the cin.ignore to reflect the size of the input and added "scoreCount--;" to remove the erroneous input. It seems to give the intended results at this point. Thanks @user4581301
    – Chris Wagner
    Nov 12 '18 at 4:39


















  • Don't you need specify n? istream& ignore (streamsize n = 1, int delim = EOF);
    – Soumya Kanti
    Nov 12 '18 at 3:55










  • I see the comment after for ( inScore =1; inScore >=1; inScore++), but if you're going to use junk code as a place holder, try to use something that makes sense. This only serves to obscure your problem.
    – user4581301
    Nov 12 '18 at 4:16










  • Suggestion: Don't BS code, write less code. Right now what you want to figure out is how to get a valid number and only a valid number. To do that, write a function that does exactly that and nothing else. Then write a simple main function that tests the function every way you can think of. Once you have the function working, worry about looping calls to the function until you hit the exit condition. Think small and then bolt the small things together into something big.
    – user4581301
    Nov 12 '18 at 4:17










  • Totally unrelated. But to get back on topic, cin.ignore(); removes only one character. You need to remove the whole bad input and probably the whole line. To do that you'll want cin.ignore(numeric_limits<streamsize>::max(), 'n') and #include <limits> to get max.
    – user4581301
    Nov 12 '18 at 4:21










  • I changed the cin.ignore to reflect the size of the input and added "scoreCount--;" to remove the erroneous input. It seems to give the intended results at this point. Thanks @user4581301
    – Chris Wagner
    Nov 12 '18 at 4:39
















Don't you need specify n? istream& ignore (streamsize n = 1, int delim = EOF);
– Soumya Kanti
Nov 12 '18 at 3:55




Don't you need specify n? istream& ignore (streamsize n = 1, int delim = EOF);
– Soumya Kanti
Nov 12 '18 at 3:55












I see the comment after for ( inScore =1; inScore >=1; inScore++), but if you're going to use junk code as a place holder, try to use something that makes sense. This only serves to obscure your problem.
– user4581301
Nov 12 '18 at 4:16




I see the comment after for ( inScore =1; inScore >=1; inScore++), but if you're going to use junk code as a place holder, try to use something that makes sense. This only serves to obscure your problem.
– user4581301
Nov 12 '18 at 4:16












Suggestion: Don't BS code, write less code. Right now what you want to figure out is how to get a valid number and only a valid number. To do that, write a function that does exactly that and nothing else. Then write a simple main function that tests the function every way you can think of. Once you have the function working, worry about looping calls to the function until you hit the exit condition. Think small and then bolt the small things together into something big.
– user4581301
Nov 12 '18 at 4:17




Suggestion: Don't BS code, write less code. Right now what you want to figure out is how to get a valid number and only a valid number. To do that, write a function that does exactly that and nothing else. Then write a simple main function that tests the function every way you can think of. Once you have the function working, worry about looping calls to the function until you hit the exit condition. Think small and then bolt the small things together into something big.
– user4581301
Nov 12 '18 at 4:17












Totally unrelated. But to get back on topic, cin.ignore(); removes only one character. You need to remove the whole bad input and probably the whole line. To do that you'll want cin.ignore(numeric_limits<streamsize>::max(), 'n') and #include <limits> to get max.
– user4581301
Nov 12 '18 at 4:21




Totally unrelated. But to get back on topic, cin.ignore(); removes only one character. You need to remove the whole bad input and probably the whole line. To do that you'll want cin.ignore(numeric_limits<streamsize>::max(), 'n') and #include <limits> to get max.
– user4581301
Nov 12 '18 at 4:21












I changed the cin.ignore to reflect the size of the input and added "scoreCount--;" to remove the erroneous input. It seems to give the intended results at this point. Thanks @user4581301
– Chris Wagner
Nov 12 '18 at 4:39




I changed the cin.ignore to reflect the size of the input and added "scoreCount--;" to remove the erroneous input. It seems to give the intended results at this point. Thanks @user4581301
– Chris Wagner
Nov 12 '18 at 4:39












1 Answer
1






active

oldest

votes


















0














Remaining Problem




Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100




Since the above current code accepts floating point values as valid inputs, we must fix the code and exclude them as invalid inputs.
For instance, if we input 1.5, 2.5 and -1, then these values are accepted and output



Number of Grades: 2
Average: 2


is shown.
Also, the current code accepts two or more integers from just one input.
If we give an input 1.5 2.5 -1, then the above output is again shown.
But we should judge 1.5, 2.5 and 1.5 2.5 -1 as invalid inputs!





Definition of the Valid Input



Since I don't know your precise definition of valid input and I may be wrong, but here I assume that it is given by the following natural statements.
First of all, as you say,




  • Each input represents an integer.


Therefore, I assume




  • Whitespace characters are allowed in the left and right side of input strings.


  • Whitespace characters between non-whitespace characters are not allowed.



In addition, I also assume




  • The first non-whitespace character must be 0, 1, ..., 9, + or -.


  • The second and the subsequent non-whitespace characters must be 0, 1, ..., 8 or 9.



Note that in my assumption the decimal-point character . is not allowed.



For instance, " 123 ", " +123 " and " -123 " are all valid inputs. But " 1 23", "+ 123", "- 123", "1.0" and "123a" are all invalid.





Validity Check Function



First, to check the validity of the input, using the following nice trimming function, we trim the input string and remove left and right whitespaces:



std::string_view trimLR(std::string_view str)
{
const auto strBegin = str.find_first_not_of(" fnrtv");
if (strBegin == std::string_view::npos){
return "";
}

const auto strEnd = str.find_last_not_of(" fnrtv");
const auto strRange = strEnd - strBegin + 1;

return str.substr(strBegin, strRange);
}


Next, we define the following simple validity check function isInteger which checks whether the passed string is an integer or not.
Here std::isdigit is useful to check each character is one of the 10 decimal digits: 0, 1, ..., 9.



My DEMO is here.



bool isInteger(std::string_view s)
{
s = trimLR(s);

if(s.empty()){
return false;
}

const std::size_t offset = ((s[0] == '-') || (s[0] == '+')) ? 1 : 0;
const auto begin = s.cbegin() + offset;


return (begin != s.cend()) // remove "+" and "-"
&& std::all_of(begin, s.cend(), (unsigned char c){
return std::isdigit(c);
});
}


In addition to this method, various interesting methods are proposed in past posts.





Main Function



Now it is easy and straightforward to implement the main for-loop.
The following code will work fine.
The input is verified to be an integer and less than 100.



int main()
{
double sumScore = 0;
int scoreCount = 0;

for(;;)
{
std::string s;
std::cout << "Please enter grades (enter a negative integer to exit): ";
std::getline(std::cin, s);

if(!isInteger(s)) {
std::cout << "Invalid number!" << std::endl;
continue;
}

const auto score = std::stoi(s);
if(score < 0) {
std::cout << "Negative number is input, Finished!" << std::endl;
break;
}
else if(score > 100) {
std::cout << "Input value is grater than 100, which is ignored." << std::endl;
continue;
}

sumScore += score;
++scoreCount;
}

const auto average = (scoreCount == 0) ? 0 : (sumScore/scoreCount);

std::cout
<< "Number of Grades: " << scoreCount << std::endl
<< "Average: " << average << std::endl;

return 0;
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255708%2fignoring-invalid-input-from-a-count-and-average%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Remaining Problem




    Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100




    Since the above current code accepts floating point values as valid inputs, we must fix the code and exclude them as invalid inputs.
    For instance, if we input 1.5, 2.5 and -1, then these values are accepted and output



    Number of Grades: 2
    Average: 2


    is shown.
    Also, the current code accepts two or more integers from just one input.
    If we give an input 1.5 2.5 -1, then the above output is again shown.
    But we should judge 1.5, 2.5 and 1.5 2.5 -1 as invalid inputs!





    Definition of the Valid Input



    Since I don't know your precise definition of valid input and I may be wrong, but here I assume that it is given by the following natural statements.
    First of all, as you say,




    • Each input represents an integer.


    Therefore, I assume




    • Whitespace characters are allowed in the left and right side of input strings.


    • Whitespace characters between non-whitespace characters are not allowed.



    In addition, I also assume




    • The first non-whitespace character must be 0, 1, ..., 9, + or -.


    • The second and the subsequent non-whitespace characters must be 0, 1, ..., 8 or 9.



    Note that in my assumption the decimal-point character . is not allowed.



    For instance, " 123 ", " +123 " and " -123 " are all valid inputs. But " 1 23", "+ 123", "- 123", "1.0" and "123a" are all invalid.





    Validity Check Function



    First, to check the validity of the input, using the following nice trimming function, we trim the input string and remove left and right whitespaces:



    std::string_view trimLR(std::string_view str)
    {
    const auto strBegin = str.find_first_not_of(" fnrtv");
    if (strBegin == std::string_view::npos){
    return "";
    }

    const auto strEnd = str.find_last_not_of(" fnrtv");
    const auto strRange = strEnd - strBegin + 1;

    return str.substr(strBegin, strRange);
    }


    Next, we define the following simple validity check function isInteger which checks whether the passed string is an integer or not.
    Here std::isdigit is useful to check each character is one of the 10 decimal digits: 0, 1, ..., 9.



    My DEMO is here.



    bool isInteger(std::string_view s)
    {
    s = trimLR(s);

    if(s.empty()){
    return false;
    }

    const std::size_t offset = ((s[0] == '-') || (s[0] == '+')) ? 1 : 0;
    const auto begin = s.cbegin() + offset;


    return (begin != s.cend()) // remove "+" and "-"
    && std::all_of(begin, s.cend(), (unsigned char c){
    return std::isdigit(c);
    });
    }


    In addition to this method, various interesting methods are proposed in past posts.





    Main Function



    Now it is easy and straightforward to implement the main for-loop.
    The following code will work fine.
    The input is verified to be an integer and less than 100.



    int main()
    {
    double sumScore = 0;
    int scoreCount = 0;

    for(;;)
    {
    std::string s;
    std::cout << "Please enter grades (enter a negative integer to exit): ";
    std::getline(std::cin, s);

    if(!isInteger(s)) {
    std::cout << "Invalid number!" << std::endl;
    continue;
    }

    const auto score = std::stoi(s);
    if(score < 0) {
    std::cout << "Negative number is input, Finished!" << std::endl;
    break;
    }
    else if(score > 100) {
    std::cout << "Input value is grater than 100, which is ignored." << std::endl;
    continue;
    }

    sumScore += score;
    ++scoreCount;
    }

    const auto average = (scoreCount == 0) ? 0 : (sumScore/scoreCount);

    std::cout
    << "Number of Grades: " << scoreCount << std::endl
    << "Average: " << average << std::endl;

    return 0;
    }





    share|improve this answer




























      0














      Remaining Problem




      Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100




      Since the above current code accepts floating point values as valid inputs, we must fix the code and exclude them as invalid inputs.
      For instance, if we input 1.5, 2.5 and -1, then these values are accepted and output



      Number of Grades: 2
      Average: 2


      is shown.
      Also, the current code accepts two or more integers from just one input.
      If we give an input 1.5 2.5 -1, then the above output is again shown.
      But we should judge 1.5, 2.5 and 1.5 2.5 -1 as invalid inputs!





      Definition of the Valid Input



      Since I don't know your precise definition of valid input and I may be wrong, but here I assume that it is given by the following natural statements.
      First of all, as you say,




      • Each input represents an integer.


      Therefore, I assume




      • Whitespace characters are allowed in the left and right side of input strings.


      • Whitespace characters between non-whitespace characters are not allowed.



      In addition, I also assume




      • The first non-whitespace character must be 0, 1, ..., 9, + or -.


      • The second and the subsequent non-whitespace characters must be 0, 1, ..., 8 or 9.



      Note that in my assumption the decimal-point character . is not allowed.



      For instance, " 123 ", " +123 " and " -123 " are all valid inputs. But " 1 23", "+ 123", "- 123", "1.0" and "123a" are all invalid.





      Validity Check Function



      First, to check the validity of the input, using the following nice trimming function, we trim the input string and remove left and right whitespaces:



      std::string_view trimLR(std::string_view str)
      {
      const auto strBegin = str.find_first_not_of(" fnrtv");
      if (strBegin == std::string_view::npos){
      return "";
      }

      const auto strEnd = str.find_last_not_of(" fnrtv");
      const auto strRange = strEnd - strBegin + 1;

      return str.substr(strBegin, strRange);
      }


      Next, we define the following simple validity check function isInteger which checks whether the passed string is an integer or not.
      Here std::isdigit is useful to check each character is one of the 10 decimal digits: 0, 1, ..., 9.



      My DEMO is here.



      bool isInteger(std::string_view s)
      {
      s = trimLR(s);

      if(s.empty()){
      return false;
      }

      const std::size_t offset = ((s[0] == '-') || (s[0] == '+')) ? 1 : 0;
      const auto begin = s.cbegin() + offset;


      return (begin != s.cend()) // remove "+" and "-"
      && std::all_of(begin, s.cend(), (unsigned char c){
      return std::isdigit(c);
      });
      }


      In addition to this method, various interesting methods are proposed in past posts.





      Main Function



      Now it is easy and straightforward to implement the main for-loop.
      The following code will work fine.
      The input is verified to be an integer and less than 100.



      int main()
      {
      double sumScore = 0;
      int scoreCount = 0;

      for(;;)
      {
      std::string s;
      std::cout << "Please enter grades (enter a negative integer to exit): ";
      std::getline(std::cin, s);

      if(!isInteger(s)) {
      std::cout << "Invalid number!" << std::endl;
      continue;
      }

      const auto score = std::stoi(s);
      if(score < 0) {
      std::cout << "Negative number is input, Finished!" << std::endl;
      break;
      }
      else if(score > 100) {
      std::cout << "Input value is grater than 100, which is ignored." << std::endl;
      continue;
      }

      sumScore += score;
      ++scoreCount;
      }

      const auto average = (scoreCount == 0) ? 0 : (sumScore/scoreCount);

      std::cout
      << "Number of Grades: " << scoreCount << std::endl
      << "Average: " << average << std::endl;

      return 0;
      }





      share|improve this answer


























        0












        0








        0






        Remaining Problem




        Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100




        Since the above current code accepts floating point values as valid inputs, we must fix the code and exclude them as invalid inputs.
        For instance, if we input 1.5, 2.5 and -1, then these values are accepted and output



        Number of Grades: 2
        Average: 2


        is shown.
        Also, the current code accepts two or more integers from just one input.
        If we give an input 1.5 2.5 -1, then the above output is again shown.
        But we should judge 1.5, 2.5 and 1.5 2.5 -1 as invalid inputs!





        Definition of the Valid Input



        Since I don't know your precise definition of valid input and I may be wrong, but here I assume that it is given by the following natural statements.
        First of all, as you say,




        • Each input represents an integer.


        Therefore, I assume




        • Whitespace characters are allowed in the left and right side of input strings.


        • Whitespace characters between non-whitespace characters are not allowed.



        In addition, I also assume




        • The first non-whitespace character must be 0, 1, ..., 9, + or -.


        • The second and the subsequent non-whitespace characters must be 0, 1, ..., 8 or 9.



        Note that in my assumption the decimal-point character . is not allowed.



        For instance, " 123 ", " +123 " and " -123 " are all valid inputs. But " 1 23", "+ 123", "- 123", "1.0" and "123a" are all invalid.





        Validity Check Function



        First, to check the validity of the input, using the following nice trimming function, we trim the input string and remove left and right whitespaces:



        std::string_view trimLR(std::string_view str)
        {
        const auto strBegin = str.find_first_not_of(" fnrtv");
        if (strBegin == std::string_view::npos){
        return "";
        }

        const auto strEnd = str.find_last_not_of(" fnrtv");
        const auto strRange = strEnd - strBegin + 1;

        return str.substr(strBegin, strRange);
        }


        Next, we define the following simple validity check function isInteger which checks whether the passed string is an integer or not.
        Here std::isdigit is useful to check each character is one of the 10 decimal digits: 0, 1, ..., 9.



        My DEMO is here.



        bool isInteger(std::string_view s)
        {
        s = trimLR(s);

        if(s.empty()){
        return false;
        }

        const std::size_t offset = ((s[0] == '-') || (s[0] == '+')) ? 1 : 0;
        const auto begin = s.cbegin() + offset;


        return (begin != s.cend()) // remove "+" and "-"
        && std::all_of(begin, s.cend(), (unsigned char c){
        return std::isdigit(c);
        });
        }


        In addition to this method, various interesting methods are proposed in past posts.





        Main Function



        Now it is easy and straightforward to implement the main for-loop.
        The following code will work fine.
        The input is verified to be an integer and less than 100.



        int main()
        {
        double sumScore = 0;
        int scoreCount = 0;

        for(;;)
        {
        std::string s;
        std::cout << "Please enter grades (enter a negative integer to exit): ";
        std::getline(std::cin, s);

        if(!isInteger(s)) {
        std::cout << "Invalid number!" << std::endl;
        continue;
        }

        const auto score = std::stoi(s);
        if(score < 0) {
        std::cout << "Negative number is input, Finished!" << std::endl;
        break;
        }
        else if(score > 100) {
        std::cout << "Input value is grater than 100, which is ignored." << std::endl;
        continue;
        }

        sumScore += score;
        ++scoreCount;
        }

        const auto average = (scoreCount == 0) ? 0 : (sumScore/scoreCount);

        std::cout
        << "Number of Grades: " << scoreCount << std::endl
        << "Average: " << average << std::endl;

        return 0;
        }





        share|improve this answer














        Remaining Problem




        Now, I need to expand upon this to make it so that the input is verified to be an integer and less than 100




        Since the above current code accepts floating point values as valid inputs, we must fix the code and exclude them as invalid inputs.
        For instance, if we input 1.5, 2.5 and -1, then these values are accepted and output



        Number of Grades: 2
        Average: 2


        is shown.
        Also, the current code accepts two or more integers from just one input.
        If we give an input 1.5 2.5 -1, then the above output is again shown.
        But we should judge 1.5, 2.5 and 1.5 2.5 -1 as invalid inputs!





        Definition of the Valid Input



        Since I don't know your precise definition of valid input and I may be wrong, but here I assume that it is given by the following natural statements.
        First of all, as you say,




        • Each input represents an integer.


        Therefore, I assume




        • Whitespace characters are allowed in the left and right side of input strings.


        • Whitespace characters between non-whitespace characters are not allowed.



        In addition, I also assume




        • The first non-whitespace character must be 0, 1, ..., 9, + or -.


        • The second and the subsequent non-whitespace characters must be 0, 1, ..., 8 or 9.



        Note that in my assumption the decimal-point character . is not allowed.



        For instance, " 123 ", " +123 " and " -123 " are all valid inputs. But " 1 23", "+ 123", "- 123", "1.0" and "123a" are all invalid.





        Validity Check Function



        First, to check the validity of the input, using the following nice trimming function, we trim the input string and remove left and right whitespaces:



        std::string_view trimLR(std::string_view str)
        {
        const auto strBegin = str.find_first_not_of(" fnrtv");
        if (strBegin == std::string_view::npos){
        return "";
        }

        const auto strEnd = str.find_last_not_of(" fnrtv");
        const auto strRange = strEnd - strBegin + 1;

        return str.substr(strBegin, strRange);
        }


        Next, we define the following simple validity check function isInteger which checks whether the passed string is an integer or not.
        Here std::isdigit is useful to check each character is one of the 10 decimal digits: 0, 1, ..., 9.



        My DEMO is here.



        bool isInteger(std::string_view s)
        {
        s = trimLR(s);

        if(s.empty()){
        return false;
        }

        const std::size_t offset = ((s[0] == '-') || (s[0] == '+')) ? 1 : 0;
        const auto begin = s.cbegin() + offset;


        return (begin != s.cend()) // remove "+" and "-"
        && std::all_of(begin, s.cend(), (unsigned char c){
        return std::isdigit(c);
        });
        }


        In addition to this method, various interesting methods are proposed in past posts.





        Main Function



        Now it is easy and straightforward to implement the main for-loop.
        The following code will work fine.
        The input is verified to be an integer and less than 100.



        int main()
        {
        double sumScore = 0;
        int scoreCount = 0;

        for(;;)
        {
        std::string s;
        std::cout << "Please enter grades (enter a negative integer to exit): ";
        std::getline(std::cin, s);

        if(!isInteger(s)) {
        std::cout << "Invalid number!" << std::endl;
        continue;
        }

        const auto score = std::stoi(s);
        if(score < 0) {
        std::cout << "Negative number is input, Finished!" << std::endl;
        break;
        }
        else if(score > 100) {
        std::cout << "Input value is grater than 100, which is ignored." << std::endl;
        continue;
        }

        sumScore += score;
        ++scoreCount;
        }

        const auto average = (scoreCount == 0) ? 0 : (sumScore/scoreCount);

        std::cout
        << "Number of Grades: " << scoreCount << std::endl
        << "Average: " << average << std::endl;

        return 0;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 23 '18 at 0:52

























        answered Nov 12 '18 at 17:32









        Hiroki

        1,0781314




        1,0781314






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255708%2fignoring-invalid-input-from-a-count-and-average%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Full-time equivalent

            Bicuculline

            さくらももこ