c++ - 将.csv读入`map>`
问题描述
我正在尝试将 .csv 文件读入map<vector<uint>>
.
.csv 文件表示一个 modbus 寄存器映射,格式为 name,register,register,register...。例如。
address,1
position,10,11
status,20,21,22
我已经尝试过了(基于https://stackoverflow.com/a/24930415/15655948),并得到了分段错误。
register_map
在头文件中声明为类属性。
int SomeClass::readCSV(std::string fileName)
{
const uint MAX_LINE_LENGTH = 1024;
const char* DELIMS = ",";
std::fstream fin(fileName);
if (!fin.is_open()) {
spdlog::get("runtime_log")->error("Could not open file {0}.", fileName);
return -1;
}
char buffer[MAX_LINE_LENGTH] = {};
char* pch;
std::vector<uint> values;
while (fin.getline(buffer, MAX_LINE_LENGTH)){
const char* row = strtok(buffer, DELIMS);
pch = strtok(NULL, DELIMS);
values.push_back(strtoul(pch,NULL,10));
while (pch != NULL){
pch = strtok(NULL, DELIMS);
values.push_back(strtoul(pch,NULL,10));
}
register_map[std::string(row)] = values;
values.clear();
}
return 1;
}
为什么我得到上面的分段错误?
解决方案
在其他假设中,关键的一个是:
while (pch != NULL) {
pch = strtok(NULL, DELIMS); //<-- pch can be NULL
values.push_back(strtoul(pch, NULL, 10)); //<-- BOOM!
}
在这里,您正在调用strtok
,它可能返回 NULL。但是你仍然继续转换字符串。这保证了未定义的行为。
要修复它,您应该颠倒逻辑,以便只转换已经过 NULL 测试的指针。
const char* row = strtok(buffer, DELIMS);
pch = strtok(NULL, DELIMS);
while (pch != NULL) {
values.push_back(strtoul(pch, NULL, 10));
pch = strtok(NULL, DELIMS);
}
通过在调试器中运行程序并一次单步执行一行代码,可以很容易地检测到这种类型的错误。调试器也可能会因此类错误而中断执行,并在崩溃时向您显示调用堆栈。所以你会看一看并想“哦,它在这里崩溃了,因为 pch 是 NULL”。
我推荐 Right Now (TM) 作为学习如何调试小程序的好时机。大多数 IDE 都带有一个集成的调试器,这使它变得更加容易。
推荐阅读
- haskell - Haskell 列出错误
- javascript - 绑定数组中不同元素的值 (JavaScript)
- r - Y 和 M 模型中样本量不均匀的 R 多级中介
- sql - 如何为我的 Reporting Services 目录中的所有报表添加内容管理员权限?
- java - 使用循环访问 Freemarker 根对象
- dart - 如何使用 Flutter 创建考试准备?
- tensorflow - Tensorflow padded_batch 用于稀疏张量?
- python - 使用现有调色板更快地量化图像?
- javascript - jQuery/Javascript - 根据图片的 src 设置点击操作
- java - Spring 似乎忽略 required=false 请求参数