【问题标题】:cramming/embedding integers into strings in C++在 C++ 中将整数填充/嵌入到字符串中
【发布时间】:2012-06-07 20:32:31
【问题描述】:

我有一些数据必须匹配某个数据包协议。我将所说的数据作为 std::string 获取。

我需要取一些整数值并将它们放在字符串中的某些位置。我不想将整数转换为字符串值;我想复制实际的字节值。

例如,如果我的字符串是“abcdefg”,并且我有一个 2 字节短的值,我想将其放在第一个位置,我不想要“a25defg”。我想要 "a" + 0x00 + 0x19 + "defg"(请原谅我。这是我能想到的最好的方式来说明我想要什么)。

有没有使用常规 C++ 字符串的巧妙方法?由于系统要求,我在这里不可能升压。

据我所见,stringstream 可能会有所帮助,但我看到的所有示例都将数字/短/整数转换为它的 ascii 版本,这不是我想要的。

我可以用 char 数组轻松做到这一点,但我想知道我是否可以用字符串做到这一点。

谢谢。

【问题讨论】:

  • 影响问题的因素有很多。首先是协议使用std::string是因为它是基于文本的协议还是std::string是对std::vector<unsigned char>的滥用,协议会处理字符串中的NUL字符吗?协议中字符串的大小是固定的吗?
  • 是的,让我们假设。在此代码被命中之前会检查字节顺序。
  • 好问题。字符串是固定大小的,因为协议是定义的。是的,协议确实需要空字符并且可以处理它们,这是使用 std::string 的原因之一。我知道如何使用 char 数组来做到这一点。我真的很好奇如何用 std::string 完成它。
  • @DavidRodríguez-dribeas 是的,std::string 可以包含 \0 字符。这是 std::strings 优于 C 类型字符串的众多优势之一!
  • 协议在备用位置使用大量 0x00 作为占位符。 0x00 是合法的。

标签: c++ string casting byte stringstream


【解决方案1】:

您说使用 char 数组很容易,但使用 std::strings 也很容易!

std::string str = "abcdef";
short val = 25;
str[1] = val>>8;
str[2] = val&255;

这就是你想要的方式。如果协议是大端的。

编辑:
仅当您要替换字符串中的现有字符时,这才有效。要从头开始创建一个新字符串,或者在末尾添加一个值,请参阅 Dani 的回答。

【讨论】:

  • 这就是我想要的。我真的需要更好地学习我的按位运算符。现在让我问你第二个问题。我怎样才能以同样的方式附加在一个短路上?我需要附加 2 个值然后使用相同的方法,还是有更好的方法?非常感谢。
  • 好吧,你不应该使用 [ ] 索引来追加字符(即写在字符串的当前结尾之后),所以你可以,例如,先追加 "xx" 然后更改内容附加的字节数。但后来它变得不那么简单和优雅的方法......
  • @MrLister:是的,我还没有看到那个。 ://
【解决方案2】:

不推荐,但你可以重新解释一下:

short something = 25;
string something_string(reinterpret_cast<unsigned char*>(&something),
                        sizeof(something));
// something_string == 19 00

不过,您需要注意字节顺序,(例如 hton

【讨论】:

  • str.append(reinterpret_cast&lt;const char*&gt;(val), sizeof(val));str.replace(1, 2, reinterpret_cast&lt;const char*&gt;(val), sizeof(val)); 为您节省极少的时间。
【解决方案3】:
template<size_t N>
void cram_helper( unsigned long long value, char* const dst )
{
    char* p = dst + N;
    while (p > dst) { *--p = value & 0xFF; value >>= 8; }
}

template<typename T>
void cram( T t, char* dst )
{
    cram_helper<sizeof(T)>(t, dst);
}

char buffer[] = { "abcdefg" };
short s = 25;
cram(s, buffer+1);

string buffer1 = "abcdefg";
cram(s, &buffer[1]);

template<size_t N, typename Container>
void cram_helper( unsigned long long value, Container& dst, int initial_index )
{
    char index = initial_index + N;
    while (index > initial_index) { dst[--index] = value & 0xFF; value >>= 8; }
}

template<typename T, typename Container>
void cram( T t, Container& dst, size_t initial_index = 0 )
{
    cram_helper<sizeof(T)>(t, dst, initial_index);
}

std::string buffer2 = "abcdefg";
short s = 25;
cram(s, buffer2, 1);

【讨论】:

  • 可以在不使用 char* 或 char 数组的情况下做到这一点吗?使用对 std::string 或 std::string 库的直接访问?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 2010-09-21
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多