C++ C++;|将字符串推入空向量会导致第一个元素损坏吗?
我一直在开发一个C++ C++;|将字符串推入空向量会导致第一个元素损坏吗?,c++,stdvector,stdstring,istringstream,C++,Stdvector,Stdstring,Istringstream,我一直在开发一个*.csv解析器,它大部分都能正常工作。基本上,解析是这样工作的: 为指定的*.csv文件打开一个流(必须在构造函数中提供文件路径、数据列数和分隔符) 获取每一行,直到文件结束。对于提取的每个原始csv行: i) 将该行流化为行流(使用std::istringstream) ii)将该流分解为更小的字符串标记(使用构造函数提供的分隔符),并推入字符串向量 提取的数据字符串可以通过私有接口数据库接口访问,直到解析器对象被销毁(或者直到我实现字符串处理器将其转换为可用数据) 解
*.csv
解析器,它大部分都能正常工作。基本上,解析是这样工作的:
*.csv
文件打开一个流(必须在构造函数中提供文件路径、数据列数和分隔符)
std::istringstream
)
ii)将该流分解为更小的字符串标记(使用构造函数提供的分隔符),并推入字符串向量
数据库
接口访问,直到解析器对象被销毁(或者直到我实现字符串处理器将其转换为可用数据)
0544,1,Kitchenware,2,27
变成:
544,1,Kitchenware,2,27
这是一个无法接受的信息丢失,但我无法找出这个问题的原因。我通过在每个数据包迭代器之前推一个伪字符串来解决这个问题
,ummy,0544,Kitchenware,27
但我仍然觉得这是一个非常糟糕的实施
我怀疑这是line_流的问题,但不完全确定如何解决
以下是源代码:
#ifndef _CSVPARSER_HPP
#define _CSVPARSER_HPP
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
const char DEFAULT_COLUMNS_SEPARATOR = ',';
class csvStream {
private:
void _setOpen() { inStream.open(fpath, ios::in); }
protected:
string fpath;
fstream inStream;
public:
explicit csvStream(const string& path) {
fpath = path;
_setOpen();
}
};
template <typename T>
class csvParser : protected csvStream {
private:
int numDataTypes;
char col_separator;
string extractedRawLine;
// Database of extracted packets of data as strings.
vector<vector<string>*> database;
// Return a reference to <data as a packet of strings>.
vector<string>& _rawToStringPacket() {
// line stream buffer & token
istringstream line_stream;
static string token;
// new packet on the heap
vector<string>* packet = nullptr;
packet = new vector<string>;
// extract strings into packet
line_stream.str(extractedRawLine);
packet->push_back("dummy");
for (int i = 1; i < numDataTypes + 1; ++i) {
getline(line_stream, token, col_separator);
packet->push_back(token);
}
return *packet;
}
/****************************PUBLIC-API****************************/
public:
// Explicit Constructor: Must supply path to a *.csv file and the number of
// data columns.
explicit csvParser(const string& path,
const int ntypes,
const char sptr = ',')
: csvStream(path), numDataTypes{ntypes}, col_separator{sptr} {}
// Extract all data while stream is open.
void extractAllRaw() {
// continue to extract data until the end of file:
while (getline(*inStream, extractedRawLine)) {
static vector<string>* temp = nullptr;
temp = &_rawToStringPacket();
database.push_back(temp);
}
}
// Stream the data elements to standard output.
void printDatabase(ostream& os = cout) {
for (auto i : database) {
for (int j = 0; j < static_cast<int>(i->size()); ++j) {
os << (*i)[j] << ",";
}
os << '\n';
}
}
};
#endif
\ifndef\u CSVPARSER\u水电站
#定义CSVPARSER水电站
#包括
#包括
#包括
#包括
使用名称空间std;
常量字符默认列分隔符=',';
类csvStream{
私人:
void _setOpen(){inStream.open(fpath,ios::in);}
受保护的:
字符串fpath;
河道内流;
公众:
显式csvStream(常量字符串和路径){
fpath=路径;
_setOpen();
}
};
模板
csvParser类:受保护的csvStream{
私人:
int numDataTypes;
煤焦分离器;
字符串提取行;
//提取数据包作为字符串的数据库。
矢量数据库;
//返回对的引用。
向量&u rawToStringPacket(){
//行流缓冲区和令牌
istringstream line_stream;
静态字符串令牌;
//堆上的新数据包
向量*数据包=nullptr;
分组=新向量;
//将字符串提取到数据包中
line_stream.str(extractedRawLine);
数据包->推回(“虚拟”);
对于(int i=1;i推回(令牌);
}
返回*数据包;
}
/****************************公共API****************************/
公众:
//显式构造函数:必须提供*.csv文件的路径和
//数据列。
显式csvParser(常量字符串和路径,
康斯特国际酒店,
常量字符sptr=',')
:csvStream(path),numDataTypes{ntypes},col_分隔符{sptr}{
//在流打开时提取所有数据。
void extractAllRaw(){
//继续提取数据,直到文件结束:
while(getline(*流内,提取行)){
静态向量*temp=nullptr;
temp=&u rawToStringPacket();
数据库。推回(临时);
}
}
//将数据元素流化为标准输出。
void printDatabase(ostream&os=cout){
用于(自动i:数据库){
对于(int j=0;jsize());++j){
操作系统请先阅读以下内容:。我发现很难相信重现问题所需的所有代码。此代码过度使用了指针和动态分配的内存。如果减少这两项,问题可能会自行解决。代码如下:string*fpath;
--为什么这是指向字符串的指针你说得对。我对内存管理想得太多了。我复制粘贴了你的代码并添加了一个main(),它对我很有用:用Windows编译器(Microsoft Visual Studio)编译的程序会处理这个问题,因为他们希望文件像Windows一样。用Unix编译器编译的程序(包括MingW)可能希望这些文件像Unix一样。carraige返回肯定能解释这一点。