c ++将文本文件读入vector ,然后根据内部向量中的第一个字写入向量或数组

时间:2021-03-13 16:38:01

this is a progression from the question I posted c++ program for reading an unknown size csv file (filled only with floats) with constant (but unknown) number of columns into an array . Im now moving onto the real application where I read in a file like:

这是我发布c ++程序的问题的进展,该程序用于读取具有恒定(但未知)列数的未知大小csv文件(仅填充浮点数)到数组中。我现在转移到我在以下文件中读取的实际应用程序:

MESH2D
MESHNAME "default coverage"
NUM_MATERIALS_PER_ELEM 1 
E4Q 1 19 20 14 16 2
E4Q 2 17 16 15 23 2
E4Q 3 22 15 14 21 2
E4Q 4 4 3 21 20 1
E4Q 5 6 20 19 7 1
E4Q 6 18 17 10 9 1
E4Q 7 17 23 12 11 1
E4Q 8 7 19 18 8 1
E4Q 9 22 1 13 23 1
E3T 10 14 20 21 2
E3T 11 21 2 22 1
E3T 12 21 3 2 1
E3T 13 22 2 1 1
E3T 14 5 20 6 1
E3T 15 20 5 4 1
E3T 16 16 14 15 2
E3T 17 23 13 12 1
E3T 18 22 23 15 2
E3T 19 17 11 10 1
E3T 20 17 18 16 2
E3T 21 8 18 9 1
E3T 22 18 19 16 2
ND 1 -3.25811078e+002 7.70285567e+001 0.00000000e+000
ND 2 -3.24209146e+002 7.60394871e+001 0.00000000e+000
ND 3 -3.23012110e+002 7.44783503e+001 0.00000000e+000
ND 4 -3.22754089e+002 7.25326647e+001 0.00000000e+000
ND 5 -3.23617358e+002 7.08079432e+001 0.00000000e+000
ND 6 -3.25161538e+002 6.98134116e+001 0.00000000e+000
ND 7 -3.27128620e+002 6.98759747e+001 0.00000000e+000
ND 8 -3.29095703e+002 6.99385378e+001 0.00000000e+000
ND 9 -3.30301095e+002 7.14667646e+001 0.00000000e+000
ND 10 -3.30786908e+002 7.33241555e+001 0.00000000e+000
ND 11 -3.30835733e+002 7.52916270e+001 0.00000000e+000
ND 12 -3.29587322e+002 7.65401204e+001 0.00000000e+000
ND 13 -3.27743000e+002 7.72270000e+001 0.00000000e+000
ND 14 -3.26108525e+002 7.32067724e+001 0.00000000e+000
ND 15 -3.27041416e+002 7.42070316e+001 0.00000000e+000
ND 16 -3.27350377e+002 7.31716751e+001 0.00000000e+000
ND 17 -3.29153676e+002 7.40024406e+001 0.00000000e+000
ND 18 -3.28659180e+002 7.19967464e+001 0.00000000e+000
ND 19 -3.26845856e+002 7.14062637e+001 0.00000000e+000
ND 20 -3.25000347e+002 7.20534611e+001 0.00000000e+000
ND 21 -3.24701329e+002 7.39638966e+001 0.00000000e+000
ND 22 -3.26167714e+002 7.53360591e+001 0.00000000e+000
ND 23 -3.28060316e+002 7.54194849e+001 0.00000000e+000
BEGPARAMDEF
GM  "Mesh"
SI  0
DY  0
TU  ""
TD  0  0
NUME  3
BCPGC  0
DISP_OPTS entity   0 0 0 0 1 0 0 0
DISP_OPTS inactive 0 0 0 0 1 0 0 0
DISP_OPTS multiple 0 0 0 0 1 0 0 0
BEFONT  0 1
DISP_OPTS entity   1 0 0 0 1 0 0 0
DISP_OPTS inactive 1 0 0 0 1 0 1 0
DISP_OPTS multiple 1 0 0 0 1 0 1 0
BEFONT  1 1
DISP_OPTS entity   2 0 0 0 1 0 0 0
DISP_OPTS inactive 2 0 0 0 1 0 1 0
DISP_OPTS multiple 2 0 0 0 1 0 1 0
BEFONT  2 1
MAT 1 "material 01"
MAT 2 "material 02"
MAT_MULTI 0
ENDPARAMDEF
BEG2DMBC
END2DMBC
BEGCURVE Version: 1
ENDCURVE 

called 'example.2dm' and try and write 3 2d vectors (or possibly (preferably) arrays) for the data stored in lines starting with E4Q E3T and ND. I want to use these cell difinitions to print a file with cell centres.

称为'example.2dm'并尝试编写3个2d向量(或可能(最好是)数组),用于存储在以E4Q E3T和ND开头的行中的数据。我想使用这些单元格定义来打印带有单元中心的文件。

I think this sort of problem is very usefull to be documented on here as my last question keeps getting views.

我认为这个问题非常有用,因为我的最后一个问题不断得到观点。

My code so far is:

到目前为止我的代码是:

// Read in CSV
//
// Alex Byasse

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>

enum case_name {e3t, e4q, nd};

case_name checkit(std::string const& inString)
{
  if (inString == "E3T") return e3t;
  if (inString == "E4Q") return e4q;
  if (inString == "ND") return nd;
}

int main()
{
    std::vector<std::vector<std::string>> values;
    std::ifstream fin("example.2dm");
    for (std::string line; std::getline(fin, line); )
    {
        std::istringstream in(line);
        values.push_back(
             std::vector<std::string>(std::istream_iterator<std::string>(in),
                          std::istream_iterator<std::string>()));
    }

    int nc = 0;
    int nn = 0;

    std::vector<std::vector<double>> cells;
    std::vector<std::vector<double>> nodes;

    for (int i = 0; i < values.size() - 1; i++) {
      switch (checkit(values[i][0])){
    case e3t:
        cells[nc].push_back(std::stod(values[i][1]));
            cells[nc].push_back(std::stod(values[i][2]));
        cells[nc].push_back(std::stod(values[i][3]));
            cells[nc].push_back(std::stod(values[i][4]));
            cells[nc].push_back(std::stod(values[i][2]));
            cells[nc].push_back(std::stod(values[i][5]));
        nc++;
        break;
      case e4q:
        cells[nc].push_back(std::stod(values[i][1]));
        cells[nc].push_back(std::stod(values[i][2]));
        cells[nc].push_back(std::stod(values[i][3]));
        cells[nc].push_back(std::stod(values[i][4]));
        cells[nc].push_back(std::stod(values[i][5]));
        cells[nc].push_back(std::stod(values[i][6]));
        nc++;
        break;
      case nd:
        nodes[nn].push_back(std::stod(values[i][1]));
        nodes[nn].push_back(std::stod(values[i][2]));
        nodes[nn].push_back(std::stod(values[i][3]));
        nn++;
        break;
     }
    }
}

Can I get some help fixing this code and also. Is this correct?

我可以帮助修复此代码吗?它是否正确?

#include <cstdlib>

Im getting the following compilation error:

我得到以下编译错误:

$ g++ read_csv2.cpp -std=c++0x
read_csv2.cpp: In function ‘int main()’:
read_csv2.cpp:44:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:45:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:46:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:47:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:48:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:49:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:53:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:54:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:55:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:56:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:57:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:58:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:62:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:63:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:64:26: error: ‘stod’ is not a member of ‘std’

I'm running g++ on cygwin. I've checked the man pages and -std=c++11 is an available option and I've tryed it yet I get the same error?

我在cygwin上运行g ++。我已经检查了手册页并且-std = c ++ 11是一个可用的选项,我尝试了但是我得到了同样的错误?

3 个解决方案

#1


1  

The places where you have cells[nc] and nodes[nd] are broken because those vectors are never increased in size.

您有单元格[nc]和节点[nd]的地方被破坏,因为这些向量的大小永远不会增加。

Here's something that may do what you need without requiring std::stod. I changed it to use all of the values from the ND lines assuming that was what you meant, if not, change the 4 to a 3 in that GetValues call.

这里可以做你需要的东西而不需要std :: stod。我将其更改为使用ND线中的所有值,假设这是您的意思,如果不是,则在GetValues调用中将4更改为3。

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>

double ToDouble(const std::string& str)
{
    std::stringstream s(str);
    double d;
    s >> d;
    return d;
}

std::vector<double> GetValues(const std::vector<std::string>& src, int start, int end)
{
    std::vector<double> ret;
    for(int i = start; i <= end; ++i)
    {
        ret.push_back(ToDouble(src[i]));
    }
    return ret;
}

void PrintValues(const std::string& title, std::vector<std::vector<double>>& v)
{
    std::cout << title << std::endl;
    for(size_t line = 0; line < v.size(); ++line)
    {
        for(size_t val = 0; val < v[line].size(); ++val)
        {
            std::cout << v[line][val] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

int main()
{
    std::vector<std::vector<std::string>> values;
    std::ifstream fin("example.2dm");
    for (std::string line; std::getline(fin, line); )
    {
        std::istringstream in(line);
        values.push_back(
            std::vector<std::string>(std::istream_iterator<std::string>(in),
            std::istream_iterator<std::string>()));
    }

    std::vector<std::vector<double>> cells;
    std::vector<std::vector<double>> nodes;
    for (size_t i = 0; i < values.size(); ++i) 
    {
        if(values[i][0] == "E3T")
        {
            cells.push_back(GetValues(values[i], 1, 5));
        }
        else if(values[i][0] == "E4Q")
        {
            cells.push_back(GetValues(values[i], 1, 6));
        }
        else if(values[i][0] == "ND")
        {
            nodes.push_back(GetValues(values[i], 1, 4));
        }
    }

    PrintValues("Cells", cells);
    PrintValues("Nodes", nodes);

    return 0;
}

#2


2  

There are a lot of compile errors produced by your program. I suggest you to give some more time in reading the basics of C++ and STL.

您的程序产生了很多编译错误。我建议你多花点时间阅读C ++和STL的基础知识。

  1. std::vector<std::vector<std::string>> values; to std::vector<std::vector<std::string> > values;. Notice the difference, some C++ compilers will take >> as the right shift operator.

    std :: vector >的值;到std :: vector >值;注意区别,一些C ++编译器将把>>作为右移位运算符。

  2. In many places in your code, you've used just vector instead of std::vector. Correct this or consider adding using namespace std; before the main function.

    在代码中的许多地方,你只使用了vector而不是std :: vector。纠正这个或考虑添加使用命名空间std;在主要功能之前。

  3. double is a primitive type. There is nothing called std::double.

    double是原始类型。什么都没有叫做std :: double。

  4. Change vector::size(values)-1 to values.size() - 1.

    将vector :: size(values)-1更改为values.size() - 1。

  5. Use ; instead of , to separate the three parts of the for statement.

    使用 ;而不是,分开for语句的三个部分。

  6. switch values[i][0] it should be switch (values[i][0]).

    切换值[i] [0]应切换(值[i] [0])。

  7. E3T is a string, so you use "E3T" instead of 'E3T'. Single quote is for characters.

    E3T是一个字符串,因此您使用“E3T”而不是“E3T”。单引号适用于角色。

  8. And C++ doesn't support switch with strings, so use if-else-if instead.

    并且C ++不支持使用字符串切换,因此请使用if-else-if。

#3


1  

The std::stod problem is odd, I thought that worked on Cygwin. What happens if you compile this program with -std=c++11?

std :: stod问题很奇怪,我认为这对Cygwin起作用了。如果使用-std = c ++ 11编译该程序会发生什么?

#include <string>
#if __cplusplus < 201103L
#warning No C++11 support
#endif

#if !defined(_GLIBCXX_USE_C99)
#warning No C99 library functions
#endif

#if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
#warning Broken vswprintf
#endif

int main() { }

Those are the preprocessor conditions necessary for libstdc++ to define std::stod so if compiling that produces any warning then you won't be able to use std::stod. You might need to use strtod(values[i][3].c_str(), nullptr) instead.

这些是libstdc ++定义std :: stod所必需的预处理器条件,因此如果编译产生任何警告,那么你将无法使用std :: stod。您可能需要使用strtod(values [i] [3] .c_str(),nullptr)。

#1


1  

The places where you have cells[nc] and nodes[nd] are broken because those vectors are never increased in size.

您有单元格[nc]和节点[nd]的地方被破坏,因为这些向量的大小永远不会增加。

Here's something that may do what you need without requiring std::stod. I changed it to use all of the values from the ND lines assuming that was what you meant, if not, change the 4 to a 3 in that GetValues call.

这里可以做你需要的东西而不需要std :: stod。我将其更改为使用ND线中的所有值,假设这是您的意思,如果不是,则在GetValues调用中将4更改为3。

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>

double ToDouble(const std::string& str)
{
    std::stringstream s(str);
    double d;
    s >> d;
    return d;
}

std::vector<double> GetValues(const std::vector<std::string>& src, int start, int end)
{
    std::vector<double> ret;
    for(int i = start; i <= end; ++i)
    {
        ret.push_back(ToDouble(src[i]));
    }
    return ret;
}

void PrintValues(const std::string& title, std::vector<std::vector<double>>& v)
{
    std::cout << title << std::endl;
    for(size_t line = 0; line < v.size(); ++line)
    {
        for(size_t val = 0; val < v[line].size(); ++val)
        {
            std::cout << v[line][val] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

int main()
{
    std::vector<std::vector<std::string>> values;
    std::ifstream fin("example.2dm");
    for (std::string line; std::getline(fin, line); )
    {
        std::istringstream in(line);
        values.push_back(
            std::vector<std::string>(std::istream_iterator<std::string>(in),
            std::istream_iterator<std::string>()));
    }

    std::vector<std::vector<double>> cells;
    std::vector<std::vector<double>> nodes;
    for (size_t i = 0; i < values.size(); ++i) 
    {
        if(values[i][0] == "E3T")
        {
            cells.push_back(GetValues(values[i], 1, 5));
        }
        else if(values[i][0] == "E4Q")
        {
            cells.push_back(GetValues(values[i], 1, 6));
        }
        else if(values[i][0] == "ND")
        {
            nodes.push_back(GetValues(values[i], 1, 4));
        }
    }

    PrintValues("Cells", cells);
    PrintValues("Nodes", nodes);

    return 0;
}

#2


2  

There are a lot of compile errors produced by your program. I suggest you to give some more time in reading the basics of C++ and STL.

您的程序产生了很多编译错误。我建议你多花点时间阅读C ++和STL的基础知识。

  1. std::vector<std::vector<std::string>> values; to std::vector<std::vector<std::string> > values;. Notice the difference, some C++ compilers will take >> as the right shift operator.

    std :: vector >的值;到std :: vector >值;注意区别,一些C ++编译器将把>>作为右移位运算符。

  2. In many places in your code, you've used just vector instead of std::vector. Correct this or consider adding using namespace std; before the main function.

    在代码中的许多地方,你只使用了vector而不是std :: vector。纠正这个或考虑添加使用命名空间std;在主要功能之前。

  3. double is a primitive type. There is nothing called std::double.

    double是原始类型。什么都没有叫做std :: double。

  4. Change vector::size(values)-1 to values.size() - 1.

    将vector :: size(values)-1更改为values.size() - 1。

  5. Use ; instead of , to separate the three parts of the for statement.

    使用 ;而不是,分开for语句的三个部分。

  6. switch values[i][0] it should be switch (values[i][0]).

    切换值[i] [0]应切换(值[i] [0])。

  7. E3T is a string, so you use "E3T" instead of 'E3T'. Single quote is for characters.

    E3T是一个字符串,因此您使用“E3T”而不是“E3T”。单引号适用于角色。

  8. And C++ doesn't support switch with strings, so use if-else-if instead.

    并且C ++不支持使用字符串切换,因此请使用if-else-if。

#3


1  

The std::stod problem is odd, I thought that worked on Cygwin. What happens if you compile this program with -std=c++11?

std :: stod问题很奇怪,我认为这对Cygwin起作用了。如果使用-std = c ++ 11编译该程序会发生什么?

#include <string>
#if __cplusplus < 201103L
#warning No C++11 support
#endif

#if !defined(_GLIBCXX_USE_C99)
#warning No C99 library functions
#endif

#if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
#warning Broken vswprintf
#endif

int main() { }

Those are the preprocessor conditions necessary for libstdc++ to define std::stod so if compiling that produces any warning then you won't be able to use std::stod. You might need to use strtod(values[i][3].c_str(), nullptr) instead.

这些是libstdc ++定义std :: stod所必需的预处理器条件,因此如果编译产生任何警告,那么你将无法使用std :: stod。您可能需要使用strtod(values [i] [3] .c_str(),nullptr)。