下面我提供了所需的 out、main.cpp、Support.cpp 和 Support.h 代码。我基本上是想提取天气数据然后输出。我修改了之前编写的使用向量的代码,现在使用单链表。我的矢量代码确实输出了不正确的数据,但它输出的数据大部分不是零。现在除了一个月之外,输出全部为零。使用 csv 文件中的命令行和管道运行时,应注释掉 main.cpp 中带有注释“完成调试时删除”的行。我仅在使用 VSCode 的调试器并单步执行程序时使用它们。这是我发现在不编辑 json 文件的情况下通过管道传输 csv 文件的最简单方法。对 Prog1a 的任何引用都是引用之前使用向量而不是列表的代码。任何帮助是极大的赞赏。我认为问题出在 Support.cpp 中定义的 insert() 函数,但我不确定。我尝试过更改它,但所发生的只是没有输出或输出全为 0,除了所需城市的一个月之外。
所需输出
unix> ./main Knoxville < weather_TN.csv
------------------------------------------
Knoxville, Tennessee (TYS)
------------------------------------------
Jan: 4.21 0.70 1.45 0.00 : 37 46 27
Feb: 7.12 1.78 3.09 0.14 : 41 47 29
Mar: 2.32 0.58 1.13 0.28 : 54 63 43
Apr: 1.78 0.44 0.71 0.26 : 58 67 50
May: 4.04 0.81 1.42 0.19 : 67 72 63
Jun: 4.17 1.04 3.11 0.00 : 77 80 74
Jul: 4.80 0.96 3.71 0.00 : 81 84 80
Aug: 2.33 0.58 1.00 0.10 : 81 83 80
Sep: 0.91 0.23 0.56 0.00 : 78 79 77
Oct: 0.18 0.04 0.14 0.00 : 65 68 64
Nov: 0.27 0.07 0.16 0.00 : 53 64 46
Dec: 5.51 1.38 2.28 0.64 : 41 43 41
主.cpp
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
#include "Support.h"
#include "Support.cpp"
void extract_values(string &text, location &n_station, data &n_data) {
//**See Prog1a
for (int i = 0; i < text.size(); i++) {
if (text[i] == ' ') {
text[i] = '_';
}
if (text[i] == ',') {
text[i] = ' ';
}
}
std::stringstream ss(text);
ss >> n_data.month >> n_station.city >> n_station.state >> n_station.geocode >> n_data.precip >> n_data.temp;
}
int main(int argc, char *argv[])
{
freopen("weather_TN.csv", "r", stdin); //REMOVE WHEN DONE DEBUGGING
if (argc != 1 && argc != 2) {
cerr << "usage: " << argv[0] << " [location] < datafile\n";
return 1;
}
char *target_location = NULL;
if (argc == 2)
target_location = argv[1];
list city_list;
string n_text;
location n_station;
data n_data;
while (getline(cin, n_text)) {
extract_values(n_text, n_station, n_data);
city_list.insert(n_station, n_data);
}
city_list.print(target_location);
fclose(stdin); //REMOVE WHEN DONE DEBUGGING
}
支持.cpp
// Add location and list member function code here.
#include "Support.h"
#include <iostream>
#include <vector>
// ... Implement the node constructor, destructor, and other functions ...
// Constructor for node
list::node::node(const location &n_station) : station(n_station) {
N = new int[12](); // Initialize and allocate arrays to zero
total_precip = new float[12]();
max_precip = new float[12]();
min_precip = new float[12]();
total_temp = new int[12]();
max_temp = new int[12]();
min_temp = new int[12]();
next = nullptr; // Initialize the next pointer to null
}
// Destructor for node
list::node::~node() {
delete[] N; // Deallocate arrays
delete[] total_precip;
delete[] max_precip;
delete[] min_precip;
delete[] total_temp;
delete[] max_temp;
delete[] min_temp;
}
list::list() {
head = new node();
head->next = nullptr;
}
list::~list() {
// Implement list destructor to delete all nodes
while (head->next != nullptr) {
node *temp = head->next;
head->next = head->next->next;
delete temp;
}
delete head;
}
void list::insert(const location &loc, const data &dat) {
// Implement list insertion logic
node *newNode = new node(loc);
newNode->next = nullptr;
node *current = head;
// Handle the case where the list is initially empty
if (current->next == nullptr || loc < current->next->station) {
newNode->next = current->next;
current->next = newNode;
// Update weather data for the new station
newNode->N[dat.month - 1] = 1;
newNode->total_precip[dat.month - 1] = dat.precip;
newNode->max_precip[dat.month - 1] = dat.precip;
newNode->min_precip[dat.month - 1] = dat.precip;
newNode->total_temp[dat.month - 1] = dat.temp;
newNode->max_temp[dat.month - 1] = dat.temp;
newNode->min_temp[dat.month - 1] = dat.temp;
return;
}
while (current->next != nullptr) {
if (loc < current->next->station) {
newNode->next = current->next;
current->next = newNode;
// Update weather data for the new station
newNode->N[dat.month - 1] = 1;
newNode->total_precip[dat.month - 1] = dat.precip;
newNode->max_precip[dat.month - 1] = dat.precip;
newNode->min_precip[dat.month - 1] = dat.precip;
newNode->total_temp[dat.month - 1] = dat.temp;
newNode->max_temp[dat.month - 1] = dat.temp;
newNode->min_temp[dat.month - 1] = dat.temp;
return;
}
current = current->next;
}
}
/*
void list::insert(const location &loc, const data &dat) {
// Implement list insertion logic
node *newNode = new node(loc);
newNode->next = nullptr;
node *current = head;
while (current->next != nullptr) {
if (loc < current->next->station) {
newNode->next = current->next;
current->next = newNode;
return;
}
current = current->next;
}
// If the station should be inserted at the end
//current->next = newNode;
}
*/
void list::node::print_station() {
std::string header = "------------------------------------------";
std::string location_info = station.city + ", " + station.state + " (" + station.geocode + ")";
printf("%s\n%s\n%s\n", header.c_str(), location_info.c_str(), header.c_str());
}
void list::node::print_data() {
std::vector<std::string> months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
for (int i = 0; i < 12; i++) {
std::vector<int> avg_temp;
avg_temp.resize(12, 0);
float tot = total_temp[i];
float avg = tot / 4;
int avgint = (int) avg;
avg_temp[i] = avgint;
printf("%s: %.2f %.2f %.2f %.2f : %d %d %d\n", months[i].c_str(), total_precip[i], total_precip[i]/12, max_precip[i], min_precip[i], avg_temp[i], max_temp[i], min_temp[i]);
}
}
void list::print(const char *target_location) {
node *current = head->next;
while (current != nullptr) {
// Check if the target_location matches, or if target_location is NULL (print all)
if (target_location == nullptr || current->station.geocode == target_location) {
current->print_station();
current->print_data();
}
current = current->next;
}
}
// Define the less-than operator for location objects
bool location::operator<(const location &other) const {
// Implement the comparison logic to sort by state first and then by city
if (state != other.state) {
return state < other.state;
}
// If states are equal, sort by city
return city < other.city;
}
// Define the equality operator for location objects
bool location::operator==(const location &other) const {
// Implement the equality logic based on state and city comparison
return (state == other.state) && (city == other.city);
}
支持.h
#ifndef SUPPORT_H
#define SUPPORT_H
#include <string>
using namespace std;
struct location {
string city;
string state;
string geocode;
bool operator<(const location &) const;
bool operator==(const location &) const;
};
struct data {
int month;
float precip;
int temp;
};
class list {
struct node {
node(const location &n_station=location());
~node();
void print_station();
void print_data();
location station;
int *N;
float *total_precip;
float *max_precip;
float *min_precip;
int *total_temp;
int *max_temp;
int *min_temp;
node *next;
};
public:
list();
~list();
void insert(const location &, const data &);
void print(const char *);
private:
node *head;
};
#endif
您的代码有很多问题。一些评论的人已经解决了其中的一些问题。我将尝试先列出它们,然后再深入挖掘。
#include <foo.cpp>
。您应该使用类似 g++ main.cpp support.cpp -o main
之类的内容来编译每个项目。using namespace std;
这有很多原因。谷歌一下为什么。你可以具体标注出你真正想用的部分,比如use std::cout;
好吧,让我们看看这个:
void extract_values(string &text, location &n_station, data &n_data) {
//**See Prog1a
for (int i = 0; i < text.size(); i++) {
if (text[i] == ' ') {
text[i] = '_';
}
if (text[i] == ',') {
text[i] = ' ';
}
}
std::stringstream ss(text);
ss >> n_data.month >> n_station.city >> n_station.state >> n_station.geocode >> n_data.precip >> n_data.temp;
}
我不知道你想在这里做什么。为什么首先将所有空格赋予下划线,将所有逗号赋予空格?你并没有忽略标题行,但你也没有对它们做任何明智的事情。并且实际数据行实际上与您在顶部列出的输入数据并不匹配。
我会在这个方法中添加
cout
语句,以确保您确实得到了您认为得到的东西。
现在,让我们看看插入。我不会太深入,但我会重写这个。我会创建一个
list::find()
方法来查找位置。我会创建一个 list::node::apply()
方法来实际应用您所读取的数据。
那么插入数据的行为就变成了:
list::node * node = list.find(n_location); if (节点 == nullptr) { 节点 = 新列表::节点(n_location); 列表.插入(节点); } 节点->apply_n_data);
这将当前 list::insert 方法的工作分开,这有点疯狂。
另请注意,您的最小/最大降水值并未设置为最小值或最大值,而只是由您最后一个月的数据中的内容写入。
这可能无法让您一路到达目标,但它应该会让您更接近目标。