【问题标题】:Problem with converting vector of string to vector of doubles将字符串向量转换为双精度向量的问题
【发布时间】:2021-08-12 13:27:42
【问题描述】:

我正在尝试编写一个程序,它从.csv 文件中读取一些数值,将它们存储在std::vector<std::string> 中,然后将这些值转换为doubles 并将它们存储在std::vector<double> 中。

我正在尝试使用 stringstreams 进行转换,过去这对我来说效果很好。

我已设法导入数值并将它们存储在std::vector<std::string> 中,但是在尝试转换为double 时遇到了一个奇怪的问题。只有第一个值存储在std::vector<double> 中,缺少很多有效数字,其他条目被忽略,根本不存储在std::vector<double> 中。

到目前为止,这是我的代码:

#include <string>
#include <fstream>
#include <iostream>
#include <sstream> 
#include <vector>

double extract_double(std::string str) 
{ 
    std::stringstream ss;
    double grade;
    //Pass all the course details to string stream
    ss << str; 
    //Extract the double type part of the string stream which is the course grade
    ss >> grade;
    str = "";
    ss.ignore();
    return grade;
}

int main()
{
    std::ifstream my_input_file;
    std::string file_name;
    my_input_file.open("scale_free_gamma_2_fitnesses.csv");
    int number_of_data_in_file;
    std::vector<std::string> fitnesses_string;
    std::vector<double> fitnesses;
    std::string string_temp;
    while (my_input_file.good()) {
        //Extract strings from file
        std::getline(my_input_file, string_temp, ',');
        fitnesses_string.push_back(string_temp);     
    }
    
    for (auto fitnesses_it = fitnesses_string.begin(); 
      fitnesses_it < fitnesses_string.end(); ++fitnesses_it){
        fitnesses.push_back(extract_double(*fitnesses_it));
    }

    for (auto fitnesses_itt = fitnesses.begin(); 
      fitnesses_itt < fitnesses.end(); ++fitnesses_itt){
        std::cout << *fitnesses_itt << std::endl;
    }
    return 0;
}

【问题讨论】:

  • 您的输入循环结构错误。了解here 的原因。
  • 你能提供输入文件的前几行吗?
  • 旁注:CSV 文件通常在每一行的末尾没有逗号,因此std::getline(my_input_file,string_temp,',') 可能会在您尝试时合并下一行中的第一个元素读取一行中的最后一个元素,所以如果您输入到程序的 CSV 文件在每行的末尾没有逗号,请记下它。
  • 一种可能的情况是您的输入文件没有您期望的格式,导致第一次转换返回一个未初始化的grade(开始初始化变量和检查错误永远不会太早) ,并且流进入错误状态。
  • CSV file 是一种格式,文件中的每一行代表一条记录,记录中的每个字段用逗号分隔。因此,记录以换行符而不是逗号结尾。您的代码不会读取 CSV 文件。您能否提供一个您尝试读取的输入示例。

标签: c++ vector filestream stringstream


【解决方案1】:

您应该先从文件中读取单独的行,然后用逗号分隔每一行。

还有更简单的方法来处理您的其余代码。

试试类似的方法:

#include <string>
#include <fstream>
#include <iostream>
#include <sstream> 
#include <vector>

int main()
{
    std::ifstream my_input_file("scale_free_gamma_2_fitnesses.csv");
    std::vector<std::string> fitnesses_string;
    std::vector<double> fitnesses;
    std::string line, string_temp;

    while (std::getline(my_input_file, line)) {
        //Extract strings from line
        std:::istringstream iss(line);
        while (std::getline(iss, string_temp, ','))
            fitnesses_string.push_back(string_temp);
    }
    
    for (const auto &s : fitnesses_string){
        fitnesses.push_back(std:stod(s));
    }

    for (auto value : fitnesses){
        std::cout << value << std::endl;
    }

    return 0;
}

在这种情况下,更简单的是完全摆脱std::vector&lt;std::string&gt;

#include <string>
#include <fstream>
#include <iostream>
#include <sstream> 
#include <vector>

int main()
{
    std::ifstream my_input_file("scale_free_gamma_2_fitnesses.csv");
    std::vector<double> fitnesses;
    std::string line, string_temp;

    while (std::getline(my_input_file, line)) {
        //Extract strings from line
        std:::istringstream iss(line);
        while (std::getline(iss, string_temp, ','))
            fitnesses.push_back(std:stod(string_temp));
    }
    
    for (auto value : fitnesses){
        std::cout << value << std::endl;
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    一些事情。首先,有一种更好的方法来循环你的向量。

    for (const std::string &str: fitnesses_string) {
    }
    

    这些被称为基于范围的 for 循环,我想你可以看到这种语法有多简洁。在现代 C++ 中,您很少需要再使用迭代器了。 (我不会说从不,但很少。)

    接下来,您的内部循环完全没有意义。相反,只需简单地做:

    for (const std::string &str: fitnesses_string) {
        fitnesses.push_back(extract_double(str));
    }
    

    现在,我们来谈谈如何将字符串转换为双精度。

    fitnesses.push_back(std::stod(str));
    

    所以你不需要你的方法。已经有方法等着你了。它在#include &lt;string&gt; 中定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-07
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多