Mark Miller
Mark Miller

Reputation: 13123

Including Missing Data in a C++ Array

I am new to C++.

Below is code that lets a user enter five elements into an array, then sums those values, and obtains the mean and a predicted future value.

The code works fine if the user enters five elements, but how do I handle the situation in which one or more values are missing?

I have written code further below that seems to solve this problem, by defining a missing value to be a negative number. That code also seems to work fine. But, is there a better, accepted way of handling missing values in a C++ array?

If I try to run the first code in Microsoft Visual Studio 2019, I do not even know what to enter for a missing value. If I do not enter anything, and just press the Enter key, nothing happens.

Here is the original code that works with five elements. This code is slightly modified from code written by Saldina Nurak:

#include <iostream>
using namespace std;
    
int nmonths = 6;
int totalmonths = 24;
    
int main()
{
    // {100, 220, 300,   0, 200, 250}
    // This line works in the command window
    // float monthArray[nmonths];
    
    // for Microsoft Visual Studio 2019
    float monthArray[6];
    
    float total = 0;
    for(int i = 0; i <= (nmonths-1); i++)
    {
        cout << "Enter Amount " << i+1 << ": ";
        cin >> monthArray[i];
        total += monthArray[i];
    }
    
    float average = total / nmonths;
    float inTwoYears = average * totalmonths;
    
    cout << "total = " << total << endl;
    cout << "average = " << average << endl;
    cout << "inTwoYears = " << inTwoYears << endl;
}
Enter Amount 1: 100
Enter Amount 2: 220
Enter Amount 3: 300
Enter Amount 4: 0
Enter Amount 5: 200
Enter Amount 6: 250
total = 1070
average = 178.333
inTwoYears = 4280

Here is the modified code I wrote that seems to handle missing values, by defining them to be negative numbers:

#include <iostream>
using namespace std;
    
int nmonths = 6;
int totalmonths = 24;
int emptycounter = 0;
    
int main()
{
    // This works from the command window
    // float monthArray[nmonths];  // {100, 220, 300,   0, -99, 250};
    
    // for Microsoft Visual Studio I have to use
    float monthArray[6];
    
    float total = 0;
    
    for(int i = 0; i <= (nmonths-1); i++)
    {
        cout << "Enter Amount " << i+1 << ": ";
        cin >> monthArray[i];
    
        if (monthArray[i] >= 0) emptycounter++;
        else (emptycounter = emptycounter);
    
        if (monthArray[i] >= 0) total += monthArray[i];
        else total = total;
    }
    
    float average = total / emptycounter;
    float inTwoYears = average * (totalmonths - (nmonths - emptycounter));
    
    cout << "total = " << total << endl;
    cout << "average = " << average << endl;
    cout << "inTwoYears = " << inTwoYears << endl;
}
C:\Users\mark_>cd C:\Users\mark_\myCppprograms
C:\Users\mark_\myCppprograms>c++ MissingDataInArray2.cpp -o MissingDataInArray2.exe -std=gnu++11
C:\Users\mark_\myCppprograms>MissingDataInArray2
Enter Amount 1: 100
Enter Amount 2: 220
Enter Amount 3: 300
Enter Amount 4: 0
Enter Amount 5: -99
Enter Amount 6: 250
total = 870
average = 174
inTwoYears = 4002

What is the standard approach for dealing with missing values in C++ and how does a user enter a missing value from the keyboard?

Upvotes: 0

Views: 593

Answers (3)

Mark Miller
Mark Miller

Reputation: 13123

Here is code that implements the answer from @vmp when missing observations are defined as NA (as in R and suggested by @Yksisarvinen in a comment) by using stoi. I have not yet figured out how to implement the answer from @Ben Voigt.

#include<iostream>
#include<vector>
#include<string>
using namespace std;

int nmonths = 6 ;
int totalmonths = 24 ;

int main()
{
     float total = 0;
     vector<int> monthArray;
     string value;

     for(int i = 0; i < nmonths; i++)
     {
          cout << "Enter Amount " << i+1 << ": ";
          cin >> value;
          if(value != "NA")
          {
               monthArray.push_back(stoi(value));
               total += stoi(value);
          }
     }

     float average = total / monthArray.size() ;
     float inTwoYears = average * (totalmonths - (nmonths - monthArray.size())) ;

     cout << "total = " << total << endl;
     cout << "average = " << average << endl;
     cout << "inTwoYears = " << inTwoYears << endl;

}

// C:\Users\mark_>cd C:\Users\mark_\myCppprograms
// C:\Users\mark_\myCppprograms>c++ vector2.cpp -o vector2.exe -std=gnu++11
// C:\Users\mark_\myCppprograms>vector2
// Enter Amount 1: 100
// Enter Amount 2: 220
// Enter Amount 3: 300
// Enter Amount 4: 0
// Enter Amount 5: NA
// Enter Amount 6: 250
// total = 870
// average = 174
// inTwoYears = 4002
 

Upvotes: 0

vmp
vmp

Reputation: 2420

You would have to define what is supposed to be a missing value if you are trying to read as a number. You could maybe read the line and try to parse it to a int and if unable to parse then it would be your missing value?

Also, you are not using C++ arrays, you are using C arrays.

C++ has an array container but vector gives you much more flexibility.

You could do something like this:

vector<int> monthArray;
int value;
for(int i = 0; i < nmonths; i++) // See the change done in the test
{
    cin >> value;
    if(value > 0)
       monthArray.push_back(value); // This would insert at the end and take care of resizing the container as needed.
}
monthArray.size(); // This returns how many elements you have in the container

Both your else clauses are assigning a variable to itself. You can erase both and put the 2 statements inside the same if:

if (monthArray[i] >= 0) 
{
    emptycounter++;
    total += monthArray[i];
}

But if you use vector you won't need emptycounter. The size of the vector will contain the number of valid elements.

for(int i = 0; i < nmonths; i++)
{
    cout << "Enter Amount " << i+1 << ": ";
    cin >> value;
    if(value > 0)
    {
       monthArray.push_back(value);
       total += value;
    }
}

After all that... There is this question: Do you really need an array? You just seem to accumulate the valid values and never refer to the array after saving the elements on it.

P.S: to use vector you need to #include<vector>

Upvotes: 1

Ben Voigt
Ben Voigt

Reputation: 283743

What is the standard approach for dealing with missing values in C++ ?

std::optional is standard and serves the need.

How does a user enter a missing value from the keyboard?

There is no definition of operator>> for istream and std::optional<float> but you can write a function that behaves the way you want.

For example you could use std::getline to always read an entire line, then if the line is blank return an empty std::optional<float> and if not then parse the number and return a std::optional<float> that contains it.

Upvotes: 0

Related Questions