所以我知道这可能是我的一个问题但是我对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 ¤ttemp, 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 ¤tWindspeed, 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 ¤ttemp, string &windDirection, int ¤tWindspeed, 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 ¤ttemp, int ¤tWindspeed, string &windDirection, string &weatherString, int temp[], int wind[],
string direction[], int &i, int &n, int &m, int &p);
void printWeather(int ¤ttemp, int ¤tWindspeed, 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 ¤ttemp, int ¤tWindspeed, 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 ¤ttemp, int ¤tWindspeed, 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;
}
答案 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可能会分配奇数长度),但访问和写入未分配的内存会调用未定义的行为,因此任何响应是合理的。