我的输出数据全是0,所以读入的数据都没有被保存,我不知道为什么。需要链表知识。语言:C++

问题描述 投票:0回答:1

下面我提供了所需的 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
c++ singly-linked-list
1个回答
0
投票

您的代码有很多问题。一些评论的人已经解决了其中的一些问题。我将尝试先列出它们,然后再深入挖掘。

  • 永远,永远,永远不要这样做
    #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 方法的工作分开,这有点疯狂。

另请注意,您的最小/最大降水值并未设置为最小值或最大值,而只是由您最后一个月的数据中的内容写入。

这可能无法让您一路到达目标,但它应该会让您更接近目标。

© www.soinside.com 2019 - 2024. All rights reserved.