0

So I know this is probably me going out on a limb but I am very new to C++ and am having difficulties writing this program. So anyways basically I have this program that is like a simple weather station. It prompts the users to input a name and how many weather histories they would like to store which sets the size of the array. After that they can input values for the weather data, print the current data, and print the ones in the history. But the issue I am having is that when the array is full and the user wants to enter more data it should simply copy all the values of the array over to the left deleting the first value at spot 0 and places new value at end. The weirdest thing is that when I run this and enter a odd number array size like 3 or 1 it works fine like it should and shifts values. But when I run it with an array value the is even like 2 or 4 it crashes. I tried debugging it but could not come across where the mistake is. Any help? Its all sloppy sorry, but I was also forced to declare everything in main and make pointers.

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

using namespace std;

void askName(string &weatherString){
int size = 0;
//Asks the user to input a name for weather statation
cout << "Please enter the name of the Weather Station, then press enter." <<       endl;
getline(cin, weatherString);
size = weatherString.length();          //gets tge length of the string just inputed

//loop is to limit the amount of characters the user can input
while (size >= 31) {
    cout << "The maximum characters allowed is 30, please try again.";
    cout << "Please enter the name of the Weather Station, then press enter." << endl;
    getline(cin, weatherString);
    size = weatherString.length();              //gets the amount of charaters from the string
}
}

void arraySize(int &i){
string myString;
loop:
while (cout << "How many histories would you like to store?" << endl && getline(cin, myString) &&
    !(stringstream(myString) >> i)) {
    cout << "That is an Invalid input, press enter to try again.\n";
    cin.clear(); //clears invalid
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discards the 
}
if (i <= 0){
    cout << "Value needs to be greater than 0, try again." << endl;
    goto loop;
}
}

void printWelcome(string &weatherString){
//Once the weather station name is subbmitted it is then printed
cout << "\nWelcome to The " + weatherString + " Weather Station" << endl;
}


int getTemperature(int &currenttemp, int &i, int temp[], int &n){

string myString;

cout << "\n";
//Tells user to input temperature but checks to make sure it is a valid input

temploop:
    while (cout << "Please enter the current temperature (In degrees Fahrenheit), then press enter." << endl && getline(cin, myString) &&
        !(stringstream(myString) >> currenttemp)) {
        cout << "That is an Invalid input, press enter to try again.\n";
        cin.clear(); //clears invalid
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discards the input
    }
    //If statements makes sure that the user input is in a reasonable range
    int maxtemp = 200;
    int mintemp = -100;
    if (currenttemp > maxtemp){
        cout << "You must have melted, try again." << endl;
        goto temploop;
    }
    else if (currenttemp < mintemp){
        cout << "You must be frozen, try again." << endl;
        goto temploop;
    }

    if (n < i){
    temp[n] = currenttemp;
    n++;
}
else{
    for (int s = 0; s < n; s++){
        temp[s] = temp[s + 1];
    }
    n = i - 1;
    temp[n] = currenttemp;
    n++;
}

return currenttemp;
}

void windFunction(int &currentWindspeed, string &windDirection, int &i, int wind[], string direction[], int &m, int &p){
string myString;

    //Asks the user to input windspeed but checks to see if the input is valid
windloop:
    while (cout << "Please enter the current wind speed (in MPH), then press enter." << endl && getline(cin, myString) &&
        !(stringstream(myString) >> currentWindspeed)) {
        cout << "That is an Invalid input, press enter to try again.\n";
        cin.clear(); //clears input
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discards the input
    }
    //Checks to make sure the input is in a reasonable range or goes back to the loop
    int minwind = 0;
    int maxwind = 300;
    if (currentWindspeed > maxwind){
        cout << "You must have blown away, try again." << endl;
        goto windloop;
    }
    else if (currentWindspeed < minwind){
        cout << "No such thing as negative wind speed, try again." << endl;
        goto windloop;
    }
    //checks to verify that the string value has not been altered from default before placing into arrray
    if (m < i){
    wind[m] = currentWindspeed;
    m++;
}
else{
    for (int s = 0; s < m; s++){
        wind[s] = wind[s + 1];
    }
    m = i - 1;
    wind[m] = currentWindspeed;
    m++;
}

//Asks the user to input the current wind direction and stores it as windDirection. Checks to see if it is a valid input
while (cout << "Please enter the current wind direction in capital letters(N, NE, NW, S, SE, SW, E, W), then press enter." << endl &&
    getline(cin, windDirection) && windDirection != "N" && windDirection != "NE" && windDirection != "NW" && windDirection != "S"
    && windDirection != "SE" && windDirection != "SW" && windDirection != "E" && windDirection != "W"){
    cout << "That is an Invalid wind direction input, press enter to try again.\n";
    cin.clear();
    cin.ignore();
}
if (p < i){
    direction[p] = windDirection;
    p++;
}
else{
    for (int s = 0; s < p; s++){
        direction[s] = direction[s + 1];
    }
    p = i - 1;
    direction[p] = windDirection;
    p++;
}

  }

//gets the complete weather input from user
void getWeather(int &currenttemp, string &windDirection, int &currentWindspeed, int temp[], int wind[], string direction[], int &i, 
int &n, int &m, int &p){
getTemperature(currenttemp, i, temp, n);
windFunction(currentWindspeed, windDirection, i, wind, direction, m, p);
 }
 void inputMenu(int &currenttemp, int &currentWindspeed, string &windDirection, string &weatherString, int temp[], int wind[], 
string direction[], int &i, int &n, int &m, int &p);

void printWeather(int &currenttemp, int &currentWindspeed, string &windDirection, string &weatherString, int temp[], int wind[], 
string direction[], int &i, int &n, int &m, int &p){
//allows user to print the current values for the weather station as long as it has already been inputed
if (currenttemp != NULL && currentWindspeed >= 0 && windDirection.length() != NULL){
    cout << "\n";
    cout << "The " << weatherString << " " << "Weather Station" << endl;
    cout << "Current Temperature: " << currenttemp << " " << "Degrees Fahrenheit" << endl;
    cout << "Current Wind Speed: " << currentWindspeed << " MPH" << " " << windDirection << endl;
}
else{
    cout << "No data has been inputed yet, please input data then try again." << endl;
    inputMenu(currenttemp, currentWindspeed, windDirection, weatherString, temp, wind, direction, i, n, m, p);              //No data found so user is sent back to option screen
}
}

void printHistory(int &currenttemp, int &currentWindspeed, string &windDirection, string &weatherString, int temp[], int wind[],
string direction[], int &i, int &n, int &m, int &p){
//allows user to print the current values for the weather station as long as it has already been inputed

if (currenttemp != NULL && currentWindspeed >= 0 && windDirection.length() != NULL){
    cout << "\n";
    cout << "Saved readings are printed newest to oldest" << endl;
    cout << "The " << weatherString << " " << "Weather Station:";

    for (int a = i - 1; a >= 0; a--){
        if (!direction[a].empty()){
            cout << "\n";
            cout << "Current Temperature: " << temp[a] << " " << "Degrees Fahrenheit" << endl;
            cout << "Current Wind Speed: " << wind[a] << " MPH" << " " << direction[a] << endl;
        }
    }
}
else{
    cout << "No data has been inputed yet, please input data then try again." << endl;
    inputMenu(currenttemp, currentWindspeed, windDirection, weatherString, temp, wind, direction, i, n, m, p);              //No data found so user is sent back to option screen
}
    }

    void inputMenu(int &currenttemp, int &currentWindspeed, string &windDirection, string &weatherString, int temp[], int wind[], 
string direction[], int &i, int &n, int &m, int &p){
int finish = 0;
//Loop which asks the user for three options to pick from
while (finish == 0){
    cout << "\nPlease select from the from the following number options and press enter:" << endl;
    cout << "1. To input a complete weather reading" << endl;
    cout << "2. To Print the current weather" << endl;
    cout << "3. To Print the weather history" << endl;
    cout << "4. To exit the program" << endl;
    cout << "\n" << endl;

    cout << "Enter your choice here: ";
    cin >> finish;                                                  //takes input from user

    system("CLS");                                              //clears screen
    cin.clear();
    cin.ignore();
    //switch statement evaluates the user input to different cases
    switch (finish) {
    case 1:
        do {
            getWeather(currenttemp, windDirection, currentWindspeed, temp, wind, direction, i, n, m, p);        //function to get the input of a complete weather reading
            finish = 0;         //sends user back to while loop menu
            system("CLS");
        } while (finish == 1);
        break;
    case 2:
        do{
            system("CLS");
            printWeather(currenttemp, currentWindspeed, windDirection, weatherString, temp, wind, direction, i, n, m, p);
            finish = 0;         //sends user back to while loop menu
        } while (finish == 2);
        break;
    case 3:
        do{
            system("CLS");
            printHistory(currenttemp, currentWindspeed, windDirection, weatherString, temp, wind, direction, i, n, m, p);
            finish = 0;         //sends user back to while loop menu
        } while (finish == 3);
        break;
    case 4:         //exits the program
        do{
            //delete[temp];
            //delete[wind];
            //delete[direction];
            exit(0);
        } while (finish == 4);
        break;
    default:
        cout << "Please enter a correct value option." << endl;
        finish = 0;         //invalid input will send user to the option screen
    }
}
}

int main(){
string weatherString;
int currenttemp = NULL;
int currentWindspeed = NULL;
string windDirection;
int i;
int n = 0;
int m = 0;
int p = 0;
int* temp;
int* wind;
string* direction;


askName(weatherString);                 //runs function to ask for name of station
system("CLS");              //clears the screen
arraySize(i);

temp = new (nothrow) int[i];
wind = new (nothrow) int[i];
direction = new (nothrow)string[i];

system("CLS");
printWelcome(weatherString);                //Welcome message saying name of station
inputMenu(currenttemp, currentWindspeed, windDirection, weatherString, temp, wind, direction, i, n, m, p);              //text driven menu for user input choices

return 0;
}
2
  • Wow, goto statements. Commented Oct 22, 2015 at 2:44
  • Compile with debugging options and run it in a debugger, that'll at least point you in the right direction, you can't expect the people to debug your code for you, especially without giving a clear input sequence that can be repeated. Commented Oct 22, 2015 at 2:44

1 Answer 1

1

You have an off by one error in your copy algorithm, which you have in 2 places.

Here is one of them:

for (int s = 0; s < n; s++){
    temp[s] = temp[s + 1];
}

n is the length of the array. When s is equal to n-1 (the last iteration) s+1 will be equal to n, which is beyond the bounds of the array.

Also I would check against i rather than n, as i is supposed to be the length.

To fix this compare against i-1 rather than i. You need to change this in 2 places.

for (int s = 0; s < i - 1; s++){
    temp[s] = temp[s + 1];
}

I don't know why it only crashes on even array lengths, maybe something to do with memory alignment (IE maybe it over allocates for the odd length), but accessing and writing to unallocated memory invokes undefined behaviour, so any response is reasonable.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.