首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在C++中将字节字符串拆分为字节向量

在C++中将字节字符串拆分为字节向量
EN

Stack Overflow用户
提问于 2014-07-24 07:57:26
回答 3查看 1.8K关注 0票数 5

我有一个字节字符串,如下所示:

代码语言:javascript
运行
AI代码解释
复制
"1,3,8,b,e,ff,10"

如何将此字符串拆分为包含以下值的std::字节向量:

0x01,0x03,0x08,0x0b,0x0e,0xff,0x10

我正在尝试使用',‘分隔符来拆分字符串,但是要让它工作起来有点困难。有人能帮我一下如何完成这个任务吗?

所以我试过这个:

代码语言:javascript
运行
AI代码解释
复制
    std::istringstream iss("1 3 8 b e ff 10");
    BYTE num = 0;
    while(iss >> num || !iss.eof()) 
    {
        if(iss.fail()) 
        {
            iss.clear();
            std::string dummy;
            iss >> dummy;
            continue;
        }
        dataValues.push_back(num);
    }

但这会将ascii字节值推到向量中:

代码语言:javascript
运行
AI代码解释
复制
49 //1
51 //3
56 //8
98 //b
101 //e
102 //f
102 //f
49 //1
48 //0

相反,我试图用以下内容填充向量:

代码语言:javascript
运行
AI代码解释
复制
 0x01
 0x03
 0x08
 0x0b
 0x0e
 0xff
 0x10
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-24 11:54:20

在我的评论中,您只是为了适应链接答案用例中出现的一些小问题而错过了:

代码语言:javascript
运行
AI代码解释
复制
    std::istringstream iss("1,3,8,b,e,ff,10");
    std::vector<BYTE> dataValues;

    unsigned int num = 0; // read an unsigned int in 1st place
                          // BYTE is just a typedef for unsigned char
    while(iss >> std::hex >> num || !iss.eof()) {
        if(iss.fail()) {
            iss.clear();
            char dummy;
            iss >> dummy; // use char as dummy if no whitespaces 
                          // may occur as delimiters
            continue;
        }
        if(num <= 0xff) {
            dataValues.push_back(static_cast<BYTE>(num));
        }
        else {
            // Error single byte value expected
        }
    }

您可以看到完全工作的示例就在这里

票数 1
EN

Stack Overflow用户

发布于 2014-07-24 09:13:34

工作样例代码(用C++11在GCC 4.9.0中测试):

文件save.txt包含:1,3,8,b,e,ff,10作为第一个和唯一的行。

输出:

代码语言:javascript
运行
AI代码解释
复制
1
3
8
b
e
ff
10

这样做的目的是:

  • 使用std::getline逐行读取。
  • 使用boost:: split 根据分隔符拆分行。
  • 用户std::stringstream将从十六进制字符串转换为无符号字符。

代码:

代码语言:javascript
运行
AI代码解释
复制
#include <fstream>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/lexical_cast.hpp>

int main(int argc, char* argv[]) {
    std::ifstream ifs("e:\\save.txt");

    std::string line;
    std::vector<std::string> tokens;
    std::getline(ifs, line);
    boost::split(tokens, line, boost::is_any_of(","));

    std::vector<unsigned char> values;
    for (const auto& t : tokens) {
        unsigned int x;
        std::stringstream ss;
        ss << std::hex << t;
        ss >> x;

        values.push_back(x);
    }

    for (auto v : values) {
        std::cout << std::hex << (unsigned long)v << std::endl;
    }

    return 0;
}
票数 0
EN

Stack Overflow用户

发布于 2014-07-24 10:12:23

为了演示另一种可能更快的处理方法,可以考虑将所有内容读入数组并使用自定义迭代器进行转换。

代码语言:javascript
运行
AI代码解释
复制
class ToHexIterator : public std::iterator<std::input_iterator_tag, int>{
    char* it_;
    char* end_;
    int current_;
    bool isHex(const char c){
        return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
    }
    char toUpperCase(const char c){
        if (c >= 'a' && c <= 'f'){
            return (c - 'a') + 'A';
        }
        return c;
    }
    int toNibble(const char c){
        auto x = toUpperCase(c);
        if (x >= '0' && x <= '9'){
            return x - '0';
        }
        else {
            return (x - 'A') + 10;
        }
    }
public:
    ToHexIterator() :it_{ nullptr }, end_{ nullptr }, current_{}{}                  //default constructed means end iterator
    ToHexIterator(char* begin, char* end) :it_{ begin }, end_{ end }, current_{}{
        while (!isHex(*it_) && it_ != end_){ ++it_; };  //make sure we are pointing to valid stuff
        ++(*this);
    }
    bool operator==(const ToHexIterator &other){
        return it_ == nullptr && end_ == nullptr && other.it_ == nullptr && other.end_ == nullptr;
    }
    bool operator!=(const ToHexIterator &other){
        return !(*this == other);
    }
    int operator*(){
        return current_;
    }
    ToHexIterator & operator++(){
        current_ = 0;
        if (it_ != end_) {
            while (isHex(*it_) && it_ != end_){
                current_ <<= 4;
                current_ += toNibble(*it_);
                ++it_;
            };
            while (!isHex(*it_) && it_ != end_){ ++it_; };
        }
        else {
            it_ = nullptr;
            end_ = nullptr;
        }
        return *this;
    }
    ToHexIterator operator++(int){
        ToHexIterator temp(*this);
        ++(*this);
        return temp;
    }
};

基本用例如下所示:

代码语言:javascript
运行
AI代码解释
复制
char in[] = "1,3,8,b,e,ff,10,--";
std::vector<int> v;
std::copy(ToHexIterator{ std::begin(in), std::end(in) }, ToHexIterator{}, std::back_inserter(v));

请注意,使用查找表执行ascii到十六进制的小转换可能更快。

速度可能非常依赖于编译器优化和平台,但是,由于一些istringstream函数是作为虚拟化或指向函数的指针(取决于标准库实现)实现的,因此优化器对它们有困难。在我的代码中,没有辅助项或函数指针,惟一的循环在std::copy实现中,优化器用来处理这些实现。通常情况下,循环速度更快,直到两个地址相等,而不是循环,直到某个变化的指针指向的事物等于某物为止。最后,所有的猜测和伏都教,但在我的机器上的MSVC13上,我的速度大约快了10倍。下面是GCC的一个活生生的例子,它在10x到3x之间,取决于运行,取决于哪个测试首先进行(可能是因为一些缓存效果)。

总之,毫无疑问还有更多的优化空间等,任何在这个抽象级别上说“我的速度总是更快”的人都在卖蛇油。

更新:使用编译时间生成的查找表将进一步提高速度:http://ideone.com/ady8GY (请注意,我增加了输入字符串的大小以减少噪声,因此这与上面的示例不直接比较)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24938606

复制
相关文章
如何更改SELinux模式
Security Enhanced Linux是一个Linux安全模块,用于强制或基于角色的访问控制。SELinux默认与CentOS和Fedora打包在一起,可以以三种模式之一运行:禁用、允许或强制执行。
温浪
2018/08/20
4.3K0
Audition如何更改音轨独奏模式 Audition更改音轨独奏模式方法【干货】+各版本安装
各版本安装获取:http://jiaocheng8.top/au.html?0ijggjk Audition是一款特别专业的电脑端音频处理软件,软件时Adobe旗下发布的,软件的兼容性非常高,能够支持
木子学Lee
2023/02/09
7980
Audition如何更改音轨独奏模式 Audition更改音轨独奏模式方法【干货】+各版本安装
更改WordPress Gutenberg编辑器的宽度
要更改WordPress Gutenberg编辑器的宽度,您需要为其加载自定义CSS规则。以下是如何快速更改宽度的概述,包括加载样式表和添加将增加Gutenberg编辑器内容区域宽度的特定规则。
许都博客
2021/06/16
8560
13 - 如何让两个列表首尾相接
1. 连接两个列表的方式有哪些? # 1. '+' a = [1, 3, 5, 6, 7] b = [2, 3, 3, 6, 8] print(a + b) # 2. extend a.extend(b) print(a) [1, 3, 5, 6, 7, 2, 3, 3, 6, 8] [1, 3, 5, 6, 7, 2, 3, 3, 6, 8] # 元组:'+' # 元组本身是只读的,没有extend方法 c = (1, 2, 3) d = (2, 3, 3, 4) print(c + d) (1,
ruochen
2021/05/22
6240
13 - 如何让两个列表首尾相接
PHPCMS更改后台编辑器样式
PHPCMS默认的后台样式用着不习惯,根前台的视觉差太大?没关系,改一下就是了。 后台编辑器样式文件 staticsjsckeditorcontents.css 把前台样式表中控制文字的那一部分拷贝进去稍微修改下即可,当然你可以自定义编辑器背景什么的,看个人喜好了。 我自己比较喜欢的样式现在分享给大家
李维亮
2021/07/09
1.4K0
CSS样式更改——列表、表格和轮廓
上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。
前端皮皮
2020/11/26
2.9K0
如何使用 Python 检查两个列表是否反向相等?
在 Python 中使用列表时,在某些情况下,您可能需要比较两个列表是否反向相等。这意味着一个列表中的元素与另一个列表中的元素相同,但顺序相反。在 Python 中,我们可以使用反转和比较列表、使用 zip() 函数、将列表转换为字符串等方法检查两个列表是否反向相等。在本文中,我们将了解这些方法,并借助各种示例检查两个列表是否反向相等。
很酷的站长
2023/08/11
2110
如何使用 Python 检查两个列表是否反向相等?
青铜和黄金选手分别怎么玩转python列表?
举个例子哈,将列表[1, 2, 3, 4, 5, 6, 7, 8, 9]中每个数字都乘以2,你能想到几种方法?
朱小五
2020/02/20
2880
青铜和黄金选手分别怎么玩转python列表?
仿 iOS 列表的编辑功能 - 删除篇
在 iOS 的设置里面,有一种编辑的效果,进入编辑状态后,列表左边推出圆形的删除按钮,点击后再出现右边确认删除按钮,相当于给用户二次确认。看下在 Android 上如何实现。
NanBox
2019/07/09
9680
更改开发编辑器背景图片
按快捷键Ctrl+Shift+A出现一个对话框 输入Set Background Image 双击Set Background Image 选择要添加的图片的路径 设置透明度 点击OK 就可以查看效果了
院长技术
2020/11/11
9930
如何更改伪元素的样式
在前端开发中我们会经常用到伪元素,有时候需要通过js来修改伪元素的样式,那么有哪几种方式来修改伪元素的样式呢?
挥刀北上
2021/01/27
9.4K0
如何更改伪元素的样式
vim的编辑模式,命令模式以及vim的实践
vim编辑模式:               从一般模式进入编辑模式,只需按i、I、a、A、o、O、r和R中的某一个键即可,当进入编辑模式时,在屏幕的尾行显示INSERT字样(若支持中文,则显示插入)。按Esc键,从编辑模式回到一般模式。              i(小写) 从目前光标所在处插入。              I (大写)从目前光标所在处第一个非空格开始插入。              a 从光标所在处的下一个字符开始插入。              A 从光标所在处行的最后一个字符卡是插入
叶瑾
2018/06/14
1.6K0
我有两个列表,现在需要找出两个列表中的不同元素,怎么做?
前几天在帮助粉丝解决问题的时候,遇到一个简单的小需求,这里拿出来跟大家一起分享,后面再次遇到的时候,可以从这里得到灵感。
Python进阶者
2023/03/02
3.3K0
我有两个列表,现在需要找出两个列表中的不同元素,怎么做?
[Linux] 更新源地址列表及更改方法 [Ubuntu 16.04 LTS]
在修改source.list前,最好先备份一份,以便日后恢复 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 修改更新源:sudo gedit /etc/apt/sources.list 最后执行更新命令:sudo apt-get update
轻舞飞扬SR
2021/02/24
1.3K0
vim 列编辑模式
vim 有三种编辑模式,命令模式、输入模式、视窗模式,我们常用的是前两种模式,但是视窗模式还是非常不错的,进入 vim 编辑器,模式是命令模式,可以通过 i、a 等进入输入模式,也可以通过 v、 c+v 进入视窗模式。
王清培
2019/07/01
3.2K0
vim 列编辑模式
如何更改 Ubuntu 的终端的颜色
但是,如果你想要一个独一无二的的终端体验或者符合你自身品位的一些东西,你也可以改变你的 Ubuntu 的终端的颜色。
用户1880875
2021/11/08
14.7K0
小知识:vi如何使用列编辑模式快速插入
经常需要用到列编辑这种操作,现在很多超文本的编辑器都可以轻松实现。 但有时需要在vi界面直接使用,但是vi的列编辑操作因不常使用总是忘记现查。 这次干脆记录下加深印象。 vi编辑某个文本时,比如修改一个oracle的参数文件,历史实验时取的实例名字是jyzhao, 如今实验我已经成功改成prod了,如下:
Alfred Zhao
2022/06/02
1.4K0
取两个列表的交集_js两个数组取差集
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/10
3.5K0
点击加载更多

相似问题

两个日期选择片段-如何分别编辑日期?

24

SwiftUI -列表编辑模式-如何更改删除按钮标题?

26

SwiftUI -如何在编辑模式下更改列表的背景

18

更改列表项处于编辑模式时的高度

10

函数返回两个列表,如何分别保存?

112
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文