Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从文件读入向量<;T>;对于二进制数据C++;_C++_Templates_Binary_Stdvector - Fatal编程技术网

C++ 从文件读入向量<;T>;对于二进制数据C++;

C++ 从文件读入向量<;T>;对于二进制数据C++;,c++,templates,binary,stdvector,C++,Templates,Binary,Stdvector,有一个模板要从文件中填充向量: template<typename T, typename A> void fill_vector_from_file(const std::string &filePath, std::vector<T, A> & target) { std::ifstream is(filePath, std::ifstream::in); is.seekg(0, std::ifstream::end); s

有一个模板要从文件中填充
向量

template<typename T, typename A>
void fill_vector_from_file(const std::string  &filePath, std::vector<T, A> & target)
{
    std::ifstream is(filePath, std::ifstream::in);

    is.seekg(0, std::ifstream::end);
    std::size_t size = is.tellg();
    is.seekg(0, std::ifstream::beg);
    target.reserve(size);

std::string line;
while (std::getline(is, line))
{
    std::istringstream line_in(line);
    while (line_in)
    {
        T val = 0;
        if (line_in >> val)
        {
            target.push_back(val);
        }
    }
}
is.close();
对于二进制文件

2 
-3
4
010
111
001
当我用
std::vector v1
检查模板中的整数时 而
std::vector v2
v2[0]
的结果是
0
而不是
010

(我想,我应该使用无符号字符来存储二进制文件)


问题:是否有任何方法修改模板,以便
v2[0]
的结果与预期一致(
010
)。

此代码有很多错误,但您最初的问题有以下答案:

将0-1 ASCII字符串转换为整数。对于类型为
无符号字符的val,您的代码
行在>>val
中读取单个字符,如“0”和“1”。您希望将由“0”和“1”组成的ASCII字符串(构成基数为2的数字)转换为整数。 在这里,您会发现
val=std::stoi(line,nullptr,2)为您执行此操作


因此,-3”和“101”都不是整数,而是表示base-10和base-2中整数的字符串,stoi()为您进行整数转换。但是,对于base-10,iostream
操作符>>()
也可以工作。(您还可以查看
std::setbase()

第二个文件似乎包含二进制格式的字符串。让我们假设它们总是3位长,在这种情况下,如果使用
std::bitset
,您将完整读取每个数字。如果使用
无符号字符
,则一次只能读取一位数字。这是您的函数,通过读取不同文件(我想您之前知道的格式)的示例稍作修改。另外还有一个示例,说明如何在需要时将
std::bitset
向量转换为
无符号字符

#include <vector>
#include <iostream>
#include <string>
#include <fstream>
#include <bitset>
#include <algorithm> // std::transform

template<typename T, typename A>
void fill_vector_from_file(std::string const &filePath, std::vector<T, A> &vec)
{
    std::ifstream ifs(filePath);
    T val;

    while (ifs >> val)
        vec.push_back(val);
}

int main()
{
    // make sample files
    std::ofstream ofs("myfile.txt");
    ofs << "2\n" << "-3\n" << "4\n";
    ofs.close();
    ofs.open("myfile2.txt");
    ofs << "010\n" << "111\n" << "001\n";
    ofs.close();


    // fill <int> vector
    std::vector<int> vi;
    fill_vector_from_file("myfile.txt", vi);
    // print int vector
    for (auto n : vi)
        std::cout << n << std::endl;


    // fill <bitset> vector 
    std::vector<std::bitset<3>> vbs;
    fill_vector_from_file("myfile2.txt", vbs);
    // print bitset vector
    for (auto n : vbs)
        std::cout << n << std::endl;


    // [OPTIONAL] convert to vector <unsigned char>
    std::vector<unsigned char> vuc(vbs.size());
    std::transform(vbs.begin(), vbs.end(), vuc.begin(),
        [](std::bitset<3> const &bs) -> unsigned char { return static_cast<unsigned char>(bs.to_ulong()); });
    // print vector <unsigned char>
    for (auto n : vuc)
        std::cout << int(n) << std::endl;


    return 0;
}

无符号字符的大小仅为1字节。您正在以文本文件的形式逐行读取该文件。当然,将像
“2”
这样的行作为
int
读取效果很好,因为
操作符>
支持这种转换。但是您不能将像
“010”
这样的行作为
无符号字符来读取。STL没有用于读取二进制数字字符串的I/O操纵器。显示的代码将读取单个字符,因此它将改为
'0'
'1'
'0'
。您必须添加额外的代码逻辑来读取
“010”
行,并应用您自己的转换逻辑将其转换为
无符号字符(0x02)。真可惜。谢谢:您必须阅读第二个文件,因为您知道数据存储为表示二进制的字符串。目前,您的模板中似乎没有这种检测功能。>>我想,我应该使用unsigned char来存储二进制文件,您可以尝试对type
t
使用
std::bitset
,然后稍后将其转换为
unsigned char
2
-3
4
010
111
001
2
7
1