首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我编写了一个头文件,以便正确地在文本文件中写入德语umlauts。

我编写了一个头文件,以便正确地在文本文件中写入德语umlauts。
EN

Code Review用户
提问于 2021-07-16 19:26:59
回答 1查看 486关注 0票数 -1

这个函数是关于在另一个cpp文件中使用一个std::wstring,以便能够从控制台读取带有德语umlauts的字符串。由于在std::ofstream已经访问文本文件时很难将wstring转换为文本文件,因此使用utf8.h将该wstring转换为一个普通的std::string。现在,16位字符代表的是两个神秘字符(我知道这是合乎逻辑的)。A变成了Ÿ,A变成了圣保罗,就像你在日常生活中经常看到的那样。这是用这个.h和.cpp文件纠正的。

我的意思是:

我的问题是:你能不能回顾一下这个函数,说出你对代码的看法?我之所以问这个问题,是因为代码大量地将一个向量复制到另一个向量,而且,正如您在最后一行中看到的,我需要去掉“剩余”空字符。我希望更经常地包含头文件和cpp文件,所以我希望两者都是好的。

handle_German_umlauts.cpp

代码语言:javascript
复制
#include "handle_German_umlauts.h"

Umlaute_korrigieren::Umlaute_korrigieren()
{
}

Umlaute_korrigieren::~Umlaute_korrigieren()
{
}

std::vector<char> Umlaute_korrigieren::_std__String_to_std__vectorChar_for_ANSI(std::string stdstring)
{
     

    std::vector<char> CString(stdstring.c_str(), stdstring.c_str() + stdstring.size() + 1);
    std::vector<char> copy(stdstring.c_str(), stdstring.c_str() + stdstring.size() + 1);

    for (size_t i = (size_t)0; i < CString.size() - (size_t)1; i++)
    {
        if (CString[i] == -61 && CString[i + 1] == -97) // Pseudo-ß gefunden
        {
            copy[i] = '\xDF'; //ß ist DF(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i+(size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }

        if (CString[i] == -61 && CString[i + 1] == -68) // Pseudo-ü gefunden
        {
            copy[i] = '\xFC'; //ü ist FC(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i + (size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }

        if (CString[i] == -61 && CString[i + 1] == -92) // Pseudo-ä gefunden
        {
            copy[i] = '\xE4'; //ä ist E4(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i + (size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }

        if (CString[i] == -61 && CString[i + 1] == -74) // Pseudo-ö gefunden
        {
            copy[i] = '\xF6'; //ö ist F6(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i + (size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }

        if (CString[i] == -61 && CString[i + 1] == -124) // Pseudo-Ä gefunden
        {
            copy[i] = '\xC4'; //Ä ist C4(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i + (size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }

        if (CString[i] == -61 && CString[i + 1] == -106) // Pseudo-Ö gefunden
        {
            copy[i] = '\xD6'; //Ö ist D6(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i + (size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }

        if (CString[i] == -61 && CString[i + 1] == -100) // Pseudo-Ü gefunden
        {
            copy[i] = '\xDC'; //Ü ist DC(hex) in ANSI
            for (size_t j = copy.size() - (size_t)1; j > (i + (size_t)1); j--) // umkopieren
            {
                copy[j - 1] = CString[j];
            }
            CString = copy;
        }
    }

    // crop unnecessary ‘\0’s
    size_t _0Counter = 0;
    for (size_t i = (size_t)0; i < CString.size(); i++)
    {
        if (CString[i] == '\0')
        {
            _0Counter += (size_t)1;
        }
    }
    size_t original = CString.size() - (size_t)1; // because the vector gets smaller due to the deletion and the for loop is always reevaluating
    size_t wie_weit = CString.size() - _0Counter;
    for (size_t i = original; i > wie_weit; i--)
    {
        CString.erase(CString.begin() + i - 1);
    }

    return CString;
}

The handle_German_umlauts.h

代码语言:javascript
复制
#ifndef HANDLE_GERMAN_UMLAUTS_H_
#define HANDLE_GERMAN_UMLAUTS_H_
#include <vector>
#include <string>
class Umlaute_korrigieren
{
public:
    Umlaute_korrigieren();
    ~Umlaute_korrigieren();
    std::vector<char> _std__String_to_std__vectorChar_for_ANSI(std::string);
private:

};
#endif // !HANDLE_GERMAN_UMLAUTS_H_

函数的调用方式如下:

代码语言:javascript
复制
std::string Strasse_als_stdstring;
utf8::utf16to8(physical_address.street.begin(), physical_address.street.end(), back_inserter(Strasse_als_stdstring));
std::vector<char> korrigierte_Strasse = Uk._std__String_to_std__vectorChar_for_ANSI(Strasse_als_stdstring);
for (size_t h = (size_t)0; h < korrigierte_Strasse.size() - (size_t)3; h++) // write to txt. -3, so that \r\n\0 aren't printed.
{
    fs8 << korrigierte_Strasse[h];
}
fs8 << " " << physical_address.house_number << std::endl;

其中,physical_address.street是std::wstring (上面提到的),for循环用于在文本文件(std::ofstream fs8)中写入字符。

EN

回答 1

Code Review用户

回答已采纳

发布于 2021-07-16 21:08:54

我看到了一些问题。

比较与计数

在最低层次上,你是重复的和低效的与你的比较。你正在“重新发现”你已经知道的信息--特别是,字符串的收缩量。

我建议您以级联方式对字符进行测试,因为它们都依赖于相同的前缀字符。

然后统计一下收缩量,这样你就不用再重复计算了。如果你要把两个字符变成一个,那么shrinkage += 2 - 1;等等。

多拷贝

在更高的层次上,您在处理Cstringcopy时效率很低。而不是“向下移动”字符的每一个特殊的字符,你应该只复制他们一次,到他们完全正确的目标位置。

你这样做:

代码语言:javascript
复制
for i in ...
    if special character at position i
        fix special character
        move all subsequent characters down by 1

这意味着如果您的字符串以2个特殊字符开始,您将处理第一个字符,将以下所有字符向下移动1,然后处理第二个字符,然后再将以下所有字符向下移动1。

相反,我认为您可以简单地复制一个字符并一个一个地复制到其中:

代码语言:javascript
复制
j = 0
for i in 0 ...
    if special character at position i:
        copy[j] = translated character
        shrinkage += ...
        j += 1
    else
        copy[j] = original[i]
        j += 1

这样,您保留两个单独的索引,但您只复制字符一次,到他们的最后位置。

幻数

没有什么比加入一堆幻数幻数魔术数字更好的方法可以让那些可怜的傻瓜去维护你的代码了,而每一种编程语言都提供了一种修复方法(通常有几种方法),而且你总是很早就学会它们,因为它太容易了。为什么你的代码里有这么多神奇的数字?

-61-97'\xDF'(size_t)1是什么意思?

整数促销

顺便说一下,(size_t)1是不必要的。如果您在某个可笑的级别上有警告,请考虑使用1U,但是如果有一个警告级别在从一个已经声明为size_t的变量中减去一个文字1时,您应该关闭它--这会使您的代码受到比C++通常更严重的污染。

去掉注释

我已经建议您重组您的代码,以摆脱所有的复制和移动。我建议您将您的if语句重组为一个由第一个字符、第二个字符组成的二级层次结构。

但我要指出的是,注释解释某事是一个很好的指示,您可以用命名对象或函数调用替换它的任何内容。

考虑到这一点:

代码语言:javascript
复制
if (CString[i] == -61 && CString[i + 1] == -97) // Pseudo-ß gefunden

现在考虑这一点:

代码语言:javascript
复制
#define SHARP_S -61, -97
#define IS_SPECIAL_CHAR(c1, c2) (CString[i]==(c1) && CString[i+1]==(c2))

if (IS_SPECIAL_CHAR(SHARP_S))

注意到我不需要评论了吗?

如果您有一个愚蠢的编码标准,或者是关于摆脱C预处理器的准宗教信仰,您可以将该宏重新编码为200行模板类或什么的,或者将其重写为内联函数(甚至!)。

名称

保持一致。您有CStringcopy,它们都是具有相同作用域的本地用户?cstringcopy怎么样?或者CStringCString2

谁认为_std__String_to_std__vectorChar_for_ANSI是个好主意?下划线、双下划线和大写?不,伙计。fix_wstring_umlaut_conversions如何?

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/264128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档