Rebekah M
Rebekah M

Reputation: 1

cout not executing outside a for loop

I'm writing a program that outputs the sum of user-input, space-separated integers (no more than 100). I'm supposed to read the values into an array such that the input "1 2 3" produces "6".

This is what I have so far:

#include <iostream>
using namespace std;

int main() {
int i= 0;
int total = 0;
int input[100];

cout << "Please enter a series of integers, space separated, that you would
enter code here`like to calculate the sum of: " << endl;

for(; i < 100; i++)
{
    cin >> input[i];
    total += input[i];
}
cout << "The sum of these values is: " << total << endl;

getchar();
return 0;
}

Coded as it is, it doesn't print the total. If I cout at the end of the for loop, then compile and enter 1 2 3, it prints 1 3 6. Which is what I would expect.

Also, when I set the array size to 5 and run it (coded as is), I figured out that if I pressed enter after each value it does print the sum of the five numbers.

But I need it to read space-separated values, not newline separated values. How can I modify this without resorting to using material I haven't learned yet (vectors, pointers...)?

Any hints, tips, or critiques would be appreciated!

Upvotes: 0

Views: 1510

Answers (7)

Galik
Galik

Reputation: 48615

I think you just need to check if the next character, after reading an int, is a space or not. If it isn't end the loop:

#include <iostream>
using namespace std;

int main()
{
    int total = 0;
    int input[100];

    cout << "Please enter... blah blah blah... the sum of: " << endl;

    for(int i = 0; i < 100; ++i)
    {
        cin >> input[i];
        total += input[i];

        // space means more to come else exit loop (break)
        if(cin.peek() != ' ')
            break;
    }

    cout << "The sum of these values is: " << total << endl;

    getchar();
    return 0;
}

Output:

Please enter... blah blah blah... the sum of: 
1 2 3
The sum of these values is: 6

The function cin.peek() returns the next character from the stream without extracting it.

Upvotes: 0

myaut
myaut

Reputation: 11504

There is a std::noskipws that allows to explicitly get whitespace separator. To check for separators (multiple separators may be passed), I have written following function:

bool wait_for_number(istream& is) {
    char ws;

    do {
        ws = is.get();

        if(!is.good())
            throw std::logic_error("Failed to read from stream!");

        if(ws == '\n')
            return false;
    } while(isspace(ws));

    if(isdigit(ws))
        is.putback(ws);
    else if(ws != '\n')
        throw std::logic_error(string("Invalid separator was used: '") + ws + "'");

    return true;
}

You'll need extra condition in the loop:

bool hasnumbers = true;
for(; hasnumbers && i < 100; i++) {
    int number;

    cin >> noskipws >> input[i];
    total += input[i];

    hasnumbers = wait_for_number(cin);
}

Note the noskipws used in expression with cin.

Some test cases:

  • These cases are working fine:

    echo '2' | ./skipws > /dev/null
    echo '1 2' | ./skipws > /dev/null
    echo '1 2 ' | ./skipws > /dev/null
    echo '1 2 3' | ./skipws > /dev/null
    echo '1   3' | ./skipws > /dev/null
    
  • This cases lead to "Failed to read from stream!":

    echo '' | ./skipws > /dev/null
    echo ' ' | ./skipws > /dev/null
    echo ' 1 2' | ./skipws > /dev/null
    
  • This case lead to "Invalid separator was used" error:

    echo '1XXX3' | ./skipws > /dev/null
    

By the way, you can use vector<int> which is easily reallocated, so your program won't be limited to 100 numbers.

Upvotes: 1

skipper
skipper

Reputation: 461

When I complied it, I got an error with the cout statement on line 9, which I was able to fix. It compiled after that and when I enter numbers it does it just fine. It'll take forever since you require 100 numbers to enter into the array, but when I changed it to ten numbers and enter 10 numbers, it works fine.

Upvotes: 0

user3995702
user3995702

Reputation:

A lot of other people seem to be addressing whitespace, but I am assuming you mean you entered those numbers on separate lines. If you are entering them on one line, this only solves half of your issue.

The main issue I see is that you are only entering 3 numbers, but running the for loop 100 times. If you enter 100 numbers, you will get a total. Most likely, this is not the behavior you want. I suggest a better way of handling this:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

int main()
{
    int total = 0;
    int input[100];

    std::string buffer = "";

    for(int i = 0; i < 100; i++)
    {
        cin >> buffer;
        if(buffer != "e")
        {
            input[i] = atoi(buffer.c_str());
            total += input[i];
        }
        else
        {
            i = 100;
        }
    }

    cout << "The sum of these values is: " << total << endl;

    getchar();
    return 0;
}

I wouldn't say this is ideal, but it works as expected. You may also want to zero the int array, depending on what you are using this for, since there is no guarantee all cells have been written to.

Upvotes: 0

Good Luck
Good Luck

Reputation: 1102

cin does not get the values all together by space, you have to enter after each single value...if you want to get the numbers all together you can take it as a string and then convert it to integer... In fact, when you enter only one string of number separated by space the cin code is not finished and it needs 99 other inputs and you cannot reach to cout

Upvotes: 0

Jagannath
Jagannath

Reputation: 4025

1) You need to take the data into string
2) split it based on space into array
3) then loop and total or use std::accumulate.

Upvotes: 0

Shay Gold
Shay Gold

Reputation: 403

You can cin all the numbers and space separators to one string. Change each space to '\0' to create a series of separate strings. Each string you can convert to integer using atoi.

Hope I helped,

Upvotes: 0

Related Questions