Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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++ 向字节向量添加字符串或字符数组_C++_Sockets - Fatal编程技术网

C++ 向字节向量添加字符串或字符数组

C++ 向字节向量添加字符串或字符数组,c++,sockets,C++,Sockets,我目前正在开发一个类来创建和读取通过网络发送的数据包,到目前为止,我使用的是16位和8位整数(无符号但仍然有效) 现在的问题是,我已经尝试了许多方法来复制它,但不知何故,缓冲区被弄坏了,出现了故障,或者结果是错误的 如果有人能给我举个有效的例子,我将不胜感激 我当前的代码可以在下面看到 谢谢,Xeross 主要的 #包括 #包括 #包括“Packet.h” 使用名称空间std; int main(int argc,字符**argv) { cout由于您正在使用std::vector作为缓冲区,您

我目前正在开发一个类来创建和读取通过网络发送的数据包,到目前为止,我使用的是16位和8位整数(无符号但仍然有效)

现在的问题是,我已经尝试了许多方法来复制它,但不知何故,缓冲区被弄坏了,出现了故障,或者结果是错误的

如果有人能给我举个有效的例子,我将不胜感激

我当前的代码可以在下面看到

谢谢,Xeross

主要的
#包括
#包括
#包括“Packet.h”
使用名称空间std;
int main(int argc,字符**argv)
{

cout由于您正在使用std::vector作为缓冲区,您也可以让它跟踪写入位置本身,避免手动调整其大小。您还可以通过使用函数模板避免写入add函数的多个重载:

template <class T>
Packet& add(T value) {
    std::copy((uint8_t*) &value, ((uint8_t*) &value) + sizeof(T), std::back_inserter(_buffer));
    return *this;
}
或者明确地说:

o.write<int>(5);
o.write(5);
要从缓冲区读取,您需要跟踪读取位置:

template <class T>
T read() {
    T result;
    uint8_t *p = &_buffer[_rpos];
    std::copy(p, p + sizeof(T), (uint8_t*) &result);
    _rpos += sizeof(T);
    return result;
}
模板
T read(){
T结果;
uint8_t*p=&u缓冲区[_RPO];
标准:复制(p,p+sizeof(T),(uint8_T*)和结果);
_rpos+=sizeof(T);
返回结果;
}
您需要显式地传递一个类型参数来读取

int i = o.read<int>();
inti=o.read();
警告:我经常使用这种模式,但由于我是在头脑中输入这种模式,代码中可能会有一些错误

编辑:我刚刚注意到,您希望能够将字符串或其他非POD类型添加到缓冲区。您可以通过模板专门化来实现这一点:

template <>
Packet& add(std::string s) {
    add(string.length());
    for (size_t i = 0; i < string.length(); ++i)
        add(string[i]);
    return *this;
}
模板
数据包和添加(标准::字符串s){
添加(string.length());
对于(大小i=0;i
这告诉编译器:如果使用字符串类型调用add,请使用此函数而不是泛型add()函数

要读取字符串,请执行以下操作:

template <>
std::string read<>() {
    size_t len = read<size_t>();
    std::string s;
    while (len--)
        s += read<char>();
    return s;
}
模板
std::string read(){
尺寸长度=读取();
std::字符串s;
而(len--)
s+=read();
返回s;
}

由于您正在使用std::vector作为缓冲区,您也可以让它跟踪写入位置本身,避免手动调整其大小。您还可以通过使用函数模板避免写入add函数的多个重载:

template <class T>
Packet& add(T value) {
    std::copy((uint8_t*) &value, ((uint8_t*) &value) + sizeof(T), std::back_inserter(_buffer));
    return *this;
}
或者明确地说:

o.write<int>(5);
o.write(5);
要从缓冲区读取,您需要跟踪读取位置:

template <class T>
T read() {
    T result;
    uint8_t *p = &_buffer[_rpos];
    std::copy(p, p + sizeof(T), (uint8_t*) &result);
    _rpos += sizeof(T);
    return result;
}
模板
T read(){
T结果;
uint8_t*p=&u缓冲区[_RPO];
标准:复制(p,p+sizeof(T),(uint8_T*)和结果);
_rpos+=sizeof(T);
返回结果;
}
您需要显式地传递一个类型参数来读取

int i = o.read<int>();
inti=o.read();
警告:我经常使用这种模式,但由于我是在头脑中输入这种模式,代码中可能会有一些错误

编辑:我刚刚注意到,您希望能够将字符串或其他非POD类型添加到缓冲区。您可以通过模板专门化来实现这一点:

template <>
Packet& add(std::string s) {
    add(string.length());
    for (size_t i = 0; i < string.length(); ++i)
        add(string[i]);
    return *this;
}
模板
数据包和添加(标准::字符串s){
添加(string.length());
对于(大小i=0;i
这告诉编译器:如果使用字符串类型调用add,请使用此函数而不是泛型add()函数

要读取字符串,请执行以下操作:

template <>
std::string read<>() {
    size_t len = read<size_t>();
    std::string s;
    while (len--)
        s += read<char>();
    return s;
}
模板
std::string read(){
尺寸长度=读取();
std::字符串s;
而(len--)
s+=read();
返回s;
}

您可以使用
std::string
作为内部缓冲区,并在添加新元素时使用

因此,添加字符串或常量char*将非常简单

添加/写入uint8可以通过将其强制转换为char、将uint16-写入长度为sizeof(uint16_t)的char*来完成

阅读uint16:

uint16_t read_int16()
{
    return ( *(uint16_t*)(m_strBuffer.c_str() + m_nOffset) );
}

您可以使用
std::string
作为内部缓冲区,并在添加新元素时使用

因此,添加字符串或常量char*将非常简单

添加/写入uint8可以通过将其强制转换为char、将uint16-写入长度为sizeof(uint16_t)的char*来完成

阅读uint16:

uint16_t read_int16()
{
    return ( *(uint16_t*)(m_strBuffer.c_str() + m_nOffset) );
}

当您只添加了四个字节时,您似乎试图从缓冲区中打印出十个字节,因此您正在运行向量的末尾。这可能会导致seg故障

此外,printf正在尝试将字符打印为带有%x的无符号整数。您需要使用
静态\u转换(packet.\u buffer[i])
作为参数

风格上:
Packet-Packet=Packet();
可能导致构造两个对象。只需使用
Packet-Packet;


通常尽量避免使用受保护的属性(受保护的方法很好),因为它们会减少类的封装。

当您只添加了四个字节时,您似乎试图从缓冲区中打印出十个字节,因此您正在运行向量的末尾。这可能会导致seg错误

此外,printf正在尝试将字符打印为带有%x的无符号整数。您需要使用
静态\u转换(packet.\u buffer[i])
作为参数

风格上:
Packet-Packet=Packet();
可能导致构造两个对象。只需使用
Packet-Packet;


通常尽量避免使用受保护的属性(受保护的方法也可以)因为它们减少了类的封装。

您的问题表明追加字符串或字符数组有问题,但我看不到尝试这样做的代码。不要混合使用printf和cout。只使用cout。stdio.h和类似的也不推荐使用。例如,对于每个C头,只需在其前面键入C,然后删除.hJust to m注意:您也可以为add()使用模板方法,并使用sizeof而不是硬编码的类型长度。为了避免代码重复,这是一个强大的启动标志。太棒了。@xeross:它可以用于您的代码设计的任何类型;)换句话说,如果您只想添加基本整数,请保持这种方式,只需替换1和2即可