因此,我目前能够使用ifstream从csv文件中读取一些十六进制值。我能够读取值并将它们分配给字符串变量。但是我想将它们转换为uint8_t
值。所以本质上我想要这样的uint8_t A = 0x41;
我尝试了atoi
,stoi
和strtol
,但是我似乎没有得到任何有效的输出。(我可能错误地使用了它们)
int read_csv(){
using namespace std;
ifstream fin;
fin.open("simpletrajhex.txt");
while (fin.good ()){
char[] line;
getline (fin, line, ',');
uint8_t hex1 = (uint8_t)stoi(line,NULL,16);
cout << line << " " << hex1 << endl;
}
return 1;
}
当我读取csv文件时,我得到了类似的东西
0xFF
0x5F
0x02
0x00
0xFF
但是这些是字符串,我需要将每个值都转换为uint8_t
当我尝试转换时,什么都没有显示。
答案 0 :(得分:0)
您无法像在uint8_t
变量中那样存储 hex 值,因此无法使用uint8_t A = 0x41
。取而代之的是,您必须将与 hex 的 decimal 等效的数字放入uint8_t
中。 / p>
尝试使用std::stoul
获得与 hex 等效的 十进制 ,并获得 hex ,在需要时从 十进制 返回。
答案 1 :(得分:0)
您的代码有很多问题,但是有两个主要问题与您转换为uint8_t
有关。尝试使用.csv
读取getline (fin, line, ',');
文件的一个普遍问题是您无法跟踪每一行中存在的值的数量。使用','
分隔符读取将导致getline
跳过行尾,并简单地读取下一个值,直到遇到EOF
。最好用line
将整行读入getline (fin, line);
,然后从stringstream
创建一个line
,使您可以读取行中的值,直到到达字符串流的末尾(将值转换限制为每行中的值转换)。
将值存储为uint8_t
的主要障碍是您无法进行 validate (验证),因为stoi
转换的结果在uint8_t
的范围内进行分配。此外,由于uint8_t
是一个unsigned
值,因此更适合使用stoul
。尽管强制转换为(uint8_t)
的C样式有效,但最好使用static_cast<uint8_t>(...)
(尽管两者都提供相同的结果)。最后,由于<< hex1 ...
运算符期望一个<<
(或int
)值,因此您尝试输出unsigned
的尝试将始终失败。
将所有这些部分放在一起,您可以重新制作read_csv()
以将文件名作为参数打开,而不是对函数中的文件名进行硬编码(不要这样做),并执行类似的操作:
int read_csv (const string& name)
{
string line;
ifstream fin (name);
while (getline (fin, line)) { /* read entire line into line */
stringstream ss (line); /* create stringstream from line */
string field; /* string to hold each field */
cout << "line: " << line << '\n';
while (getline (ss, field, ',')) { /* read each hex value from line */
uint64_t tmp = stoul (field, 0, 0); /* convert to uint64_t */
if (tmp <= UINT8_MAX) { /* validate in range of uint8_t */
uint8_t hex1 = static_cast<uint8_t>(tmp); /* store uint8_t */
/* output with cast to unsigned for << */
cout << " " << field << " -> " <<
static_cast<uint32_t>(hex1) << '\n';
}
}
}
return 1;
}
注意,而不是cout
中的大小写,您也可以在hex1
之前加上数字+
以强制进行促销,例如
cout << " " << field << " -> " << +hex1 << '\n';
还请注意:使用0
作为stoul
中的基数,会自动检测到数字基数:如果前缀为 0 ,基数为八进制,如果前缀为 0x 或 0X ,则基数为十六进制,否则基数为十进制。
使用该功能的简短示例可能是:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdint>
using namespace std;
int read_csv (const string& name)
{
string line;
ifstream fin (name);
while (getline (fin, line)) { /* read entire line into line */
stringstream ss (line); /* create stringstream from line */
string field; /* string to hold each field */
cout << "line: " << line << '\n';
while (getline (ss, field, ',')) { /* read each hex value from line */
uint64_t tmp = stoul (field, 0, 0); /* convert to uint64_t */
if (tmp <= UINT8_MAX) { /* validate in range of uint8_t */
uint8_t hex1 = static_cast<uint8_t>(tmp); /* store uint8_t */
/* output with cast to unsigned for << */
cout << " " << field << " -> " <<
static_cast<uint32_t>(hex1) << '\n';
}
}
}
return 1;
}
int main (int argc, char **argv) {
if (argc < 2) {
cerr << "error: insufficient input\n" <<
"usage: " << argv[0] << " <file>\n";
return 1;
}
read_csv (argv[1]);
}
(注意:通常鼓励使用using namespace std;
,因此尽管它可以简化简短示例程序的键入,但通常您希望避免在每个示例程序中都包含整个std
源文件(尤其是避免将其包含在头文件中)
示例输入文件
$ cat dat/hexcsv.csv
0xff,0x5f
0x02,0x00
0xff,0xaa
使用/输出示例
每个数字值都存储在uint8_t
变量hex1
中,然后以十进制输出。
$ ./bin/read_csv_uint8 dat/hexcsv.csv
line: 0xff,0x5f
0xff -> 255
0x5f -> 95
line: 0x02,0x00
0x02 -> 2
0x00 -> 0
line: 0xff,0xaa
0xff -> 255
0xaa -> 170