Tim Rowland
Tim Rowland

Reputation: 37

Randomly printing out size of int, no idea why

For some reason this code is printing out the size of an int after getting multiple inputs. I am a beginner in c++ and I would really appreciate it if someone could help me out and help me understand why this is happening. Thanks.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int calculateVowelIndex(std::string input)
{
float numVowel = 0, numCon = 0;
int vowelIndex;

std::vector<char> vowels{ 'a', 'e', 'i', 'o', 'u', 'y' };

std::transform(input.begin(), input.end(), input.begin(), ::tolower);

for (int x = 0; x < input.length(); ++x)
{
    if (std::find(vowels.begin(), vowels.end(), input[x]) != vowels.end())
        ++numVowel;

    else
        ++numCon;
}

vowelIndex = numVowel / (numVowel + numCon) * 100;

return vowelIndex;
}

int main()
{
int n;
std::string input;
std::vector<std::string> words;
std::vector <unsigned int> vowelIndexes;
std::cin >> n;

for (int x = 0; x < n; ++x)
{
    std::getline(std::cin, input);
    words.push_back(input);
    vowelIndexes.push_back(calculateVowelIndex(input));
}

for (int x = 0; x < words.size(); ++x)
{
    std::cout << vowelIndexes.at(x) << " " << words.at(x) << std::endl;
}

std::cin.get();
}

Upvotes: 1

Views: 55

Answers (1)

user7881131
user7881131

Reputation:

My best guess is that this happens because when you type in the input, there ends up being an extra newline that then gets gobbled by the first iteration of std::getline. Once you've typed in the input for the number of words, std::cin's buffer could look like this:

"3\n"

The std::cin >> n; parse the integer and stops when it reaches the newline, leaving this in std::cin:

"\n"

The first call then to std::getline reads in all the characters (which there are none here) until it reaches a newline (the '\n'), which it then reads and discards, leaving nothing in std::cin. So a blank line is read in and passed to the function on the first iteration.

This leaves two more iterations of the loop. The next two calls to std::getline have no input to read from std::cin, so it prompts you for more, and the loop processes it accordingly.

if I input 3, and then 2 words, after the second word it prints out the size of an int (2,147,483,647) and doesn't let me input the 3rd word.

This is why that happens: a forgotten newline is read in and taken as the end of an empty line.

To remedy this, we must read any left over characters in the line and discard them before reading any more lines. This can be done with the ignore method on std::cin, like so:

// ...
std::cin >> n;

// skip the rest of the line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

for (int x = 0; x < n; ++x)
// ...

std::numeric_limits is in <limits>. This reads and discards every character until it encounters the newline character, which it then reads and discards.

Alternatively, because it looks like you just want a word, why not just use the method that reads one word?

std::cin >> input;

Upvotes: 2

Related Questions