为 ISO 8859-1 实现 basic_string<unsigned char>

Posted

技术标签:

【中文标题】为 ISO 8859-1 实现 basic_string<unsigned char>【英文标题】:Implementing basic_string<unsigned char> for ISO 8859-1 【发布时间】:2014-05-04 16:06:41 【问题描述】:

背景:

我是一名 C 程序员,我刚刚决定尝试使用 C++。

目标:

创建一个类以使用 std::basic_string 将 ISO 8859-1 字符作为字符串读取。我知道我可以在 std::string 中使用映射函数,但出于学习原因,我想尝试这种方式。

问题:

我创建了一个从 char_traits 扩展的类和一个实现 basic_string 的类。现在我正在尝试创建构造函数。 构造函数应该接受一个 const char 指针并为其分配空间。

基于this,这个构造函数已经存在:

basic_string (const charT* s, const allocator_type& alloc = allocator_type());

它被定义为:

来自 c 字符串

Copies the null-terminated character sequence (C-string) pointed by s.
The length is determined by calling traits_type::length(s)."

所以我假设我可以重用该构造函数,传递正确的参数(在这种情况下,是 unsigned char 而不是 char),但要么我不知道如何正确使用默认参数,要么构造函数不存在.

我不确定这是否是正确的方法,因此欢迎提供有关如何执行此操作的任何提示/提示。

错误:

test.cpp: In constructor ‘ISO_8859_1_String::ISO_8859_1_String(const char*)’:
test.cpp:18:72: error: no matching function for call to ‘ISO_8859_1_String::ISO_8859_1_String(const unsigned char*, NULL)’
test.cpp:18:72: note: candidates are:
test.cpp:16:5: note: ISO_8859_1_String::ISO_8859_1_String(const char*)
test.cpp:16:5: note:   candidate expects 1 argument, 2 provided
test.cpp:14:7: note: ISO_8859_1_String::ISO_8859_1_String(const ISO_8859_1_String&)
test.cpp:14:7: note:   candidate expects 1 argument, 2 provided

代码:

#include <iostream>

using namespace std;

class ISO_8859_1_Char_Traits : public char_traits<unsigned char>
  public: 
    // Simple length implementation
    static size_t length (const unsigned char* s)
      size_t i = 0;
      while (s[i++] != 0x00);
      return i;
    
;

class ISO_8859_1_String : public basic_string<unsigned char, ISO_8859_1_Char_Traits, allocator<unsigned char> >
  public:
    ISO_8859_1_String(const char* s)
      ISO_8859_1_String(reinterpret_cast<const unsigned char*>(s), NULL);
   
;

int main()
  ISO_8859_1_String* test = new ISO_8859_1_String("test");
  
  return 1;

【问题讨论】:

【参考方案1】:

在这个:

class ISO_8859_1_String : public basic_string<unsigned char, ISO_8859_1_Char_Traits, allocator<unsigned char> >
  public:
    ISO_8859_1_String(const char* s)
      ISO_8859_1_String(reinterpret_cast<const unsigned char*>(s), NULL);
   
;

要么是我的眼睛在欺骗我,要么你正在调用构造函数(在构造函数本身中,事实证明)使用错误数量的参数。此外,即使您传递了正确数量的参数,您也会无限递归。

编辑:另外,第一个参数的类型无论如何都不匹配。

EDIT2:好的,我想我知道你想要做什么。您正在尝试将参数传递给基类的构造函数。为此,您需要不同的语法:

    ISO_8859_1_String(const char* s)
     : basic_string<unsigned char, ISO_8859_1_Char_Traits, allocator<unsigned char> >(reinterpret_cast<const unsigned char*>(s), NULL) 
   

另外,我会使用一些类型别名或 typedef 来使其更具可读性。

附录:基类 ctor 参数必须通过初始化列表传递,而不是在派生类 ctor 的主体中:

class A 
    A() 
    A(int) 
;

class B1 : public A
    // This means: Call the base class ctor with a 1.
    B1() : A(1) ]
    // This means: Call the base class ctor with no arguments.  Then create a
    // temporary A object, passing 1 to the ctor, and then throw it away.
    // B1()  A(1); 
;

【讨论】:

感谢您的回答,但我确实想使用具有不同参数的构造函数。正如我的问题中所述,我想使用 basic_string 中的默认构造函数之一,并且我声明的构造函数是一种 wrap-and-fix 构造函数,只是为了正确调用默认值。 但是ISO_8859_1_String 没有与您的调用匹配的构造函数。在 C 中,这就像在原型为 void foo(double *x) 时尝试调用 foo(1, "a")。换句话说,层次结构中的每个类都有自己的一组构造函数。 等等,我想我知道你现在要做什么了。我会编辑答案。 就在现场,先生!但现在我有更多问题:为什么“ISO_8859_1_String(const char* s): uString(reinterpret_cast(s))”可以,但是“ISO_8859_1_String(const char* s)uString(reinterpret_cast (s));" 不是吗? (假设 uString 是您请求的 typedef)-(您可以通过将“cout size() 因为它们的含义不同。它基本上只是语法。不幸的是,在 cmets 提供的非常有限的格式中很难显示,所以我将在答案中添加一个附录。

以上是关于为 ISO 8859-1 实现 basic_string<unsigned char>的主要内容,如果未能解决你的问题,请参考以下文章

java怎样实现将GB2312编码的字符串转换为ISO-8859-1编码的字符串

有没有办法从UTF8转换为iso-8859-1?

有没有办法从 UTF8 转换为 ISO-8859-1?

将组合 diaerese 转换为 ISO 8859-1

将 ISO-8859-1 转换为 UTF-8 [重复]

在 Java 中将 UTF-8 转换为 ISO-8859-1 - 如何将其保持为单字节