【问题标题】:C++ reading some bytes at a memory address, output as stringC ++在内存地址读取一些字节,输出为字符串
【发布时间】:2012-02-02 07:59:59
【问题描述】:

一个函数从一个未知的 DLL 返回一个指针和一个长度(通过参数)。

Result = SpamnEggs( &pBytes, &nBytes )

指针指向一个有效的内存地址,在该地址处有 nBytes 个连续字节。 这些字节包含文本的有效 ascci 值。没有空终止!

我的任务是在输出之前在通用 C++ 代码(不使用复杂库或使用字节)中以少量 简单 操作“覆盖”某种字符串类型:

cout << sresult

添加: 无需复制字节,因为这是一个必须遍历的大缓冲区。

原型:

int SpamnEggs( void* pBytes, void* nBytes );

becomes

int SpamnEggs( char** pBytes, int* nBytes );

非常感谢大家。很好的答案,而且都非常有效。

【问题讨论】:

  • 覆盖意味着不允许复制字符序列?或者这是一种可能的方法?
  • 你应该创建一个全新的类来处理这些字符串?或者你可以使用std::string my_string(static_cast&lt;char*&gt;(pointer), length)吗?
  • 可以使用 std:string 是的。让我测试一下这个想法……
  • @Joachim Pileborg:此构造函数复制整个字符串。那不是他想做的。
  • @Mike: std::string 将复制缓冲区。

标签: c++ arrays string function pointers


【解决方案1】:

你可以从指针和长度构造一个 std::string。

std::string sResult(pBytes, nBytes);
std::cout << sResult;

(假设 pBytes 是一个 char* 指针,否则你需要一个小演员表)。

【讨论】:

  • 我可以从 Void* 更改原型
  • 这是一个简单而干净的方法。但它复制了我认为/认为不是 OP 意图的源数据。
  • @Kit - 就像我对这个问题的评论一样:“如果我们写信给cout,额外的副本会引人注目吗?”。做 I/O 比构造字符串要复杂得多。
  • @Bo Persson:同意,这只是解释解决方案之间差异的一句话。根据数据的大小和目标流,它可能会有所不同。
【解决方案2】:

您可以复制原始内存并自己添加字符串终止字符:

char* newStr = new char[size + 1];
memcpy ( newStr, source, size );
newStr[size] = "\0";
cout << newStr;

在不复制内存的情况下,您可以创建一个将指针和长度作为成员保存的类,并重载流运算符以仅打印length 字符:

class MyString
{
   void* _pBuf;
   int _length;
public:
   MyString(void* pBuf, int length)
   {
      _pBuf = pBuf;
      _length = length;
   }

   friend ostream& operator <<(ostream &os,const MyString& obj);
};


ostream& operator <<(ostream &os,const MyString& obj)
{
   const char* pChar = (const char*)obj._pBuf;
   for ( int i = 0 ; i < obj._length ; i++ )
   {
      os << pChar[i];
   }
   return os;
}

示例用法:

   char* x = "blablabla";
   int length = 3;
   MyString str(x,length);
   cout << str;

【讨论】:

  • 抱歉忘了说,没有copymem。
  • 不是作业,结束了漫长的一天,为一个不会吓坏客户的演示应用程序做一个简单的灵魂!
  • 非常好的解决方案,技术上也很棒......只是笔记太多了。
【解决方案3】:

这样的(未经测试)代码怎么样:

class my_pointer_string
{
    friend std::ostream &operator<<(std::ostream &, const my_pointer_string &);

public:
    my_pointer_string(void *ptr, size_t len)
        : m_pointer(ptr), m_length(len)
        { }

private:
    void  *m_pointer;
    size_t m_length;
};

std::ostream &operator<<(std::ostream &os, const my_pointer_string &str)
{
    char *string = reinterpret_cast<char *>(str.m_pointer);
    for (size_t i = 0; i < str.m_length; i++)
        os << *string++;
    return os;
}

【讨论】:

  • 很好,但想的很简单,只需几行代码,这样他们就不会从重要的代码中分心
【解决方案4】:

你需要做的是

a) 创建一些封装 char 指针和大小的类。

b) 为该类编写一个

编辑:与 Bo Persson 的回应相反,这并不意味着复制源数据。

【讨论】:

  • 它必须简单且符合要求
  • 我相信所有东西都没有办法内联。该类可以非常轻量级,并且移位运算符是一行(只需循环并输出每个字符)。完成后,实际调用将如下所示: cout
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
相关资源
最近更新 更多