在数组C ++中移位字符串值的问题

时间:2015-10-22 02:32:28

标签: c++ arrays string

所以我知道这可能是我的一个问题但是我对C ++很陌生并且在编写这个程序时遇到了困难。所以无论如何基本上我有这个程序,就像一个简单的气象站。它会提示用户输入一个名称以及他们想要存储多少天气历史记录,这些天气历史记录设置了数组的大小。之后,他们可以输入天气数据的值,打印当前数据,并打印历史数据。但我遇到的问题是,当阵列已满并且用户想要输入更多数据时,它应该简单地将数组的所有值复制到左侧,删除第0点的第一个值并将新值放在结尾处。最奇怪的是,当我运行它并输入一个奇数数字大小(如3或1)时,它应该正常工作并移动值。但是当我使用数组值运行它时,它甚至会像2或4那样崩溃。我试过调试它,但无法遇到错误的地方。有帮助吗?这一切都是草率的抱歉,但我也被迫宣布一切都在主要并指出。

#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;
}

1 个答案:

答案 0 :(得分:1)

你的复制算法中有一个错误,你有2个地方。

以下是其中之一:

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

n是数组的长度。当s等于n-1(最后一次迭代)时,s + 1将等于n,这超出了数组的范围。

我也会检查i而不是n,因为我应该是长度。

要解决这个与i-1而不是i的比较。你需要在2个地方改变它。

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

我不知道为什么它只会在数组长度上崩溃,也许与内存对齐有关(IE可能会分配奇数长度),但访问和写入未分配的内存会调用未定义的行为,因此任何响应是合理的。