【问题标题】:How to convert integers represented as string to ASCII symbols?如何将表示为字符串的整数转换为 ASCII 符号?
【发布时间】:2019-09-29 17:07:36
【问题描述】:

我有一个如下所示的输入字符串:“126022034056098012”。这是我从某个文件中读取的符号的 ASCII 代码连接的结果。例如,代码是 126 22 34 56 98 12。问题是如何将此字符串解码回字符?注意:字符串不能包含除数字以外的任何分隔符(\、| 等)。接下来我该怎么做?

我想出了一种使用 ASCII 符号映射的方法:key->string 与 ASCII 符号的数字表示,value->ASCII 符号。在循环中,我将传入的数字累积在一个字符串中,直到该字符串与映射中的某个键匹配。匹配时,我将生成的代码转换为字符。我继续,直到我用完输入数据。但这种方法适用于字符串和 txt 文件,但不适用于二进制文件。

从 ASCII 码字符串生成字符串的函数:

string Utils::from_number_to_ascii(string number, int size) {
    Utils ut;
    while(number.size() % 3) {
        number = "0" + number;
    }

    string out;
    for (int i = 0; i < size;){
        string st;
        auto it = ut.triple_dict.end();
        while (it == ut.triple_dict.end() && i < size){
            st += number[i++];
            it = ut.triple_dict.find(st);
        }
        out += it->second;
        st = "";
    }
    return out;
}

填满地图:

Utils::Utils() {
    for (int i = 0; i <= 255; i++){
        string s =  to_string(static_cast<int>(i));
        if (s.size() == 1) {
            s = "00" + s;
        } if (s.size() == 2){
            s = "0" + s;
        }
        triple_dict.insert(make_pair(s, static_cast<unsigned char>(i)));
    }
}

不难看出我用三个字节填充了容器:如果符号的ASCII码是两位数,我在它后面加上“0”,如果符号的代码是一位数,我在它后面加上“ 00" 使代码三位数字。我这样做是为了明确解码符号。

【问题讨论】:

  • 程序如何知道它必须使用代码 126 还是 12?通常,如果您不使用分隔符,您将使用固定大小(在您的示例中为 3 位),因此实际输入应该是 126022034056098012。否则,如果您的意思是 126 126,您的程序无法知道您是否输入了 126126或 12 61 26 或 126 1 2 6 或 12 6 126...等
  • 是的,你是对的。我使用固定大小的代码。我忘了编辑我的问题。
  • 我感兴趣的一个问题是如何将此方法应用于二进制文件或如何以不同的方式进行。
  • 如何简单地将字符串每隔三个字符拆分一次并将每个片段(应该是十进制数字的 3 个字符)转换为一个 int 值?该 int 值将是初始字符的 ASCII 码。

标签: c++ string char integer converters


【解决方案1】:

如果每个 ascii 代码正好由 3 位数字表示,我们可以很容易地通过循环来做到这一点:

std::string toAscii(char const* digits, size_t size) {
    std::string output(size / 3, '\0');
    for(char& c : output) {
        char d0 = *digits++; // Get 3 digits
        char d1 = *digits++;
        char d2 = *digits++; 

        int ascii_value = (d0 - '0') * 100 + (d1 - '0') * 10 + (d2 - '0'); 
        c = (char)ascii_value; 
    }
    return output; 
}

示例用法

我有一个带有示例输入的 c 字符串,以及一个带有预期输出的字符串。该程序验证它们是否相等。

int main() {
    auto&& input = "126022034056098012";
    std::string expected_output = {char(126), char(22), char(34), char(56), char(98), char(12)};
    std::cout << (toAscii(input, sizeof(input)) == expected_output); // Prints true
}

fstream.write() 是否在文件末尾添加'\0'?

否。如果您的字符串包含 0 字符,它会添加它,否则不会添加。我们可以用一些非常简短的示例代码自己测试一下。

#include <fstream>
#include <iostream>
#include <string>

int main()
{
    {
        std::ofstream file("test.txt");
        std::string   message = "Hello!";

        file.write(message.data(), message.length());
        // file gets closed automatically 
    }
    {
        std::ifstream file("test.txt");


        while (file)
        {
            std::cout << file.get() << '\n';
        }
        // file gets closed automatically
    }
}

当我编译并运行这段代码时,它会输出以下内容。每个值对应"Hello!"中对应字符的值,除了最后一个。 -1 表示您已到达文件末尾,但如果您使用file.read 之类的方法,则不会显示。 \0 不会出现在文件中的任何位置。

72
101
0
108
111
33
-1

【讨论】:

  • 这很有趣。你能告诉我,如何将c字符串(char const *)写入最终没有“\0”符号的二进制文件吗? fstream.write() 是否写入此符号 (\0)?此命令 (fstream.write((char *)str.c_str() , str.length());) 是否将字符串写入二进制文件而没有结束字符?
  • 它写入不带 '\0' 的字符串。我在答案中添加了一些代码来显示这一点!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2016-08-01
  • 1970-01-01
相关资源
最近更新 更多