从文件读到矢量 逐行工作对二进制数据C ++不正确

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从文件读到矢量 逐行工作对二进制数据C ++不正确相关的知识,希望对你有一定的参考价值。

有一个模板可以从文件中填充vector <T>

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();

文件中的数据可以是int或binary,每行存储一个数字,例如: 对于int:

2 
-3
4

对于二进制:

010
111
001

当我用std::vector<int> v1检查模板的整数和std::vector<unsigned char> v2时,v2[0]的结果是0而不是010。 (我想,我应该使用unsigned char来存储二进制文件)

问题:有没有办法修改模板,所以v2[0]的结果将如预期的那样(010)。

答案

第二个文件似乎包含二进制格式的字符串。假设它们总是3位长,在这种情况下,如果你使用std::bitset<3>,你将完整地读取每个数字。如果你使用unsigned char,那么你一次只能读一个数字。这是你的功能,略微修改了阅读不同文件的例子(我想你手头知道的格式)。作为奖励,还有如何在需要时将std::bitset矢量转换为unsigned char的示例。

#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
" << "-3
" << "4
";
    ofs.close();
    ofs.open("myfile2.txt");
    ofs << "010
" << "111
" << "001
";
    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;
}

工作演示:http://coliru.stacked-crooked.com/view?id=42aa04e34e4194c1

2
-3
4
010
111
001
2
7
1
另一答案

此代码有很多问题,但您的原始问题有以下答案:

将0-1 ASCII字符串转换为整数。你的代码line_in >> val为val类型unsigned char读取单个字符,如'0'和'1'。您希望将由'0'和'1'组成的ASCII字符串转换为整数,该字符串形成一个base-2数字。在这个SO answer你发现val = std::stoi(line, nullptr, 2);为你做那件事。

因此,“-3”和“101”都不是整数,而是表示base-10和base-2中整数的字符串,stoi()会为您转换为整数。然而,在基数为10的情况下,iostream operator>>()也能正常工作。 (你也可以看看std::setbase()。)

以上是关于从文件读到矢量 逐行工作对二进制数据C ++不正确的主要内容,如果未能解决你的问题,请参考以下文章

AT24C02写一个数据然后读取一个数据是正确的,但是当写入多个数据时,读出数据就不正确,求指教?

从文件读取数据时的无限循环

c语言fread函数的用法

如何用C语言统计一个数据文件中的数据个数

c语言删除文件中的指定的一行数据怎么做

C/C++中如何将文件读取为二进制数据到数组中,再从数组中读取二进制流还原为文件,主要是后一步