【问题标题】:Need to write string to a file in hex format in c++需要在c ++中以十六进制格式将字符串写入文件
【发布时间】:2019-09-28 01:38:59
【问题描述】:

我有一个包含十六进制值的字符串:

string str = "e101";

我需要把它写成 2 个字节的文件。当我试图写一个文件时,它会写出如下 4 个字节的值:

65 31 30 31

我正在使用以下操作进行文件写入:

    myfile.open ("file.cf3",std::ios::binary);
    myfile << str << "\n";
    myfile.close();

但我想将其写为 2 个字节的值。

例如,如果 i g 如何将其作为 2 个字节写入文件?

std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";

我想要这样的输出

.0n..:j..}p...?*8...3..x

【问题讨论】:

  • fwrite(一个 C 函数),不将 std::string 作为其第一个参数,它采用 char*。 (在调用fwrite 之前,您必须将str 转换为unsigned short 值)然后您将写入sizeof (short) 字节数,而不是str.size() 字节...对于"65 31 30 31",请参阅ASCIITable .
  • 那么您希望将0xe10x01 这两个字节写入您的文件中吗?请edit您的问题并说清楚。此外,您的问题标题具有误导性,这与 SHA 无关。
  • 是的,我想把它写成只有 2 个字节的值
  • 好的,你已经标记了这个问题 C++,但你展示的是 C。语言是非常不同的。您可以在 C++ 中调用 C 函数,但如果您应该用 C++ 编写它,您可能希望使用 C++ 文件流接口而不是 C fwritestd::ios_base::openmode - binary

标签: c++ file hex


【解决方案1】:

我认为你的问题是模棱两可的...... 请记住,从您的字符串中,每两个字符就有 1 个字节(不是两个)。 所以你想写两个数字(意思是ascii)代表字符串的十六进制值...... 如果这是正确的解释,您需要将字符串拆分为成对的字符,然后将每个字符转换为等效的整数。 这是我的代码... 它写入标准输出,但您可以轻松修改它以便写入文件而不是屏幕。

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
using namespace std;

int main () {
        string str = "e101";
        string two_char;
        unsigned char byte;

        for (int i=0 ; i<str.size(); i+=2) {
                two_char = str.substr(i,2);
                byte = strtol(two_char.c_str(),0,16);
                cout << two_char << " " << (int)byte <<"\n";
        }
}

【讨论】:

    【解决方案2】:

    这是一个解决方案的示例。

    #include <fstream>
    #include <iostream>
    #include <string>
    
    int main() {
        std::ofstream file("file.txt", std::ios::binary);
        if(!file.is_open())  {
            return -1;
        }
        std::string str("e101");
        for (std::size_t i = 0; i < str.length() - 1; ++++i) {
            file << static_cast<char>(str[i] * 16 + str[i + 1]);
        }
        file.close();
    }
    

    您可以简单地遍历您的字符串并将两个字符作为一个字节。您将第一个字符乘以 16 并添加第二个字符。

    【讨论】:

      【解决方案3】:

      在回答关于将 2 字节以二进制形式写入 C++ 文件的原始问题时,您有一个基本的两步过程。 (1) 使用stoi 和基数16 将数字的字符串表示形式转换为数值。这提供了一个可以存储在unsigned short 中的数值。 (2) 使用f.write 将该值写入您的文件,而不是frwite,其中f 是您的打开流引用。

      如果您想将cout 的输出格式化为十六进制,那么您必须将cout 的标志设置为以十六进制格式输出数值(虽然不是您问题的直接部分,但它与流 I /O 格式(如果需要)。)

      所以基本上你有你的字符串并将其转换为数字,例如

          std::string str = "e101";
          unsigned short u = stoi(str, 0, 16);
      

      现在u 保存使用 base-16str 中的文本转换而来的数值,您可以简单地将其作为 2 字节值写入文件,例如

          std::string filename = "out.bin";   /* output filename */
          ...
          std::ofstream f (filename, f.trunc | f.binary); /* open out in binary */
          if (!f.write(reinterpret_cast<char*>(&u), sizeof u)) {  /* write 2 bytes */
              std::cerr << "error: write of short to file failed.\n";
              return 1;
          }
      

      总而言之,您可以做一些简短的事情,输出使用cout 写入的十六进制值,并将其写入文件"out.bin",例如

      #include <fstream>
      #include <iostream>
      #include <iomanip>
      #include <string>
      
      int main (void) {
      
          std::string filename = "out.bin";   /* output filename */
          std::string str = "e101";
          unsigned short u = stoi(str, 0, 16);
          /* output converted value to terminal in hex */
          std::cout.setf(std::ios::hex, std::ios::basefield);  /* set hex output */
          std::cout << "writing value to file: " << u << '\n'; /* for cout */
          /* output converted value to file */
          std::ofstream f (filename, f.trunc | f.binary); /* open out in binary */
          if (!f.write(reinterpret_cast<char*>(&u), sizeof u)) {  /* write 2 bytes */
              std::cerr << "error: write of short to file failed.\n";
              return 1;
          }
      }
      

      使用/输出示例

      $ ./bin/stoi_short
      writing value to file: e101
      

      生成的输出文件

      通过使用 hexdump 程序转储文件的内容来确认,例如

      $ hexdump out.bin
      0000000 e101
      0000002
      

      检查一下,如果您还有其他问题,请告诉我。

      【讨论】:

        猜你喜欢
        • 2013-05-03
        • 2021-10-27
        • 1970-01-01
        • 2010-11-26
        • 1970-01-01
        • 1970-01-01
        • 2014-10-07
        • 2022-07-08
        • 1970-01-01
        相关资源
        最近更新 更多