C++:有没有什么好的方法可以在函数名称中不明确说明字符类型的情况下进行读/写? (cout 与 wcout 等)

发布于 2024-08-25 23:55:29 字数 1366 浏览 3 评论 0 原文

我在让程序从基于模板的文件中读取数据时遇到问题,例如:

bool parse(basic_ifstream<T> &file)
{
    T ch;
    locale loc = file.getloc();
    basic_string<T> buf;
    file.unsetf(ios_base::skipws);
    if (file.is_open())
    {
        while (file >> ch)
        {
            if(isalnum(ch, loc))
            {
                buf += ch;
            }
            else if(!buf.empty())
            {
                addWord(buf);
                buf.clear();
            }
        }
        if(!buf.empty())
        {
            addWord(buf);
        }
        return true;
    }
    return false;
}

当我使用 实例化此类时,这会起作用,但当我使用 < code> (清楚)。

在课堂之外,我正在使用:

for (iter = mp.begin(); iter != mp.end(); ++iter )
{
    cout << iter->first << setw(textwidth - iter->first.length() + 1);
    cout << " " << iter->second << endl;
}

写入此数据结构中的所有信息(它是一个 map, int>),并且正如预测的那样,如果 cout 会爆炸>iter->first 不是 char 数组。

我在网上查了一下,共识是使用wcout,但不幸的是,由于这个程序要求可以在编译时更改模板( -> ;) 我不确定如何通过简单地选择 cout 或 wcout 来逃脱。也就是说,除非有一种方法可以在不更改大量代码的情况下读取/写入宽字符。

如果这个解释听起来有点复杂,请告诉我,我会尽力解决。

I'm having a problem getting a program to read from a file based on a template, for example:

bool parse(basic_ifstream<T> &file)
{
    T ch;
    locale loc = file.getloc();
    basic_string<T> buf;
    file.unsetf(ios_base::skipws);
    if (file.is_open())
    {
        while (file >> ch)
        {
            if(isalnum(ch, loc))
            {
                buf += ch;
            }
            else if(!buf.empty())
            {
                addWord(buf);
                buf.clear();
            }
        }
        if(!buf.empty())
        {
            addWord(buf);
        }
        return true;
    }
    return false;
}

This will work when I instantiate this class with <char>, but has problems when I use <wchar_t> (clearly).

Outside of the class, I'm using:

for (iter = mp.begin(); iter != mp.end(); ++iter )
{
    cout << iter->first << setw(textwidth - iter->first.length() + 1);
    cout << " " << iter->second << endl;
}

To write all of the information from this data struct (it's a map<basic_string<T>, int>), and as predicted, cout explodes if iter->first isn't a char array.

I've looked online and the consensus is to use wcout, but unfortunately, since this program requires that the template can be changed at compile time (<char> -> <wchar_t>) I'm not sure how I could get away with simply choosing cout or wcout. That is, unless there way a way to read/write wide characters without changing lots of code.

If this explanation sounds awkwardly complicated, let me know and I'll address it as best I can.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笛声青案梦长安 2024-09-01 23:55:29

使用特征类。您无需在代码中直接引用 cout,而是引用 traits::cout,然后将 traits 专门化为 std::cout 和 traits< ;wchar_t> 到 wcout。

已更新

template <typename T>
class traits {
public:
    static std::basic_ostream<T>& tout;
};

template<>
std::ostream& traits<char>::tout = std::cout;

template<>
std::wostream& traits<wchar_t>::tout = std::wcout;

int _tmain(int argc, _TCHAR* argv[])
{
    traits<char>::tout<<"Ascii";
    traits<wchar_t>::tout<<L"Unicode";
    return 0;
}

Use a traits class. Instead of referencing directly cout in code, you'd reference traits<T>::cout and then specialize traits<char> to std::cout and traits<wchar_t> to wcout.

Updated

template <typename T>
class traits {
public:
    static std::basic_ostream<T>& tout;
};

template<>
std::ostream& traits<char>::tout = std::cout;

template<>
std::wostream& traits<wchar_t>::tout = std::wcout;

int _tmain(int argc, _TCHAR* argv[])
{
    traits<char>::tout<<"Ascii";
    traits<wchar_t>::tout<<L"Unicode";
    return 0;
}
九歌凝 2024-09-01 23:55:29

当然,只需重新定义模板并使用 typedef:

#ifdef USE_UNICODE
typedef wchar_t tchar_t
#else
typedef unsigned char tchar_t
#endif

然后您就可以使用大多数标准 C++ 函数/容器的模板:

typedef std::basic_string<tchar_t> tstring

等等。

Sure, just redefine the templates and use a typedef:

#ifdef USE_UNICODE
typedef wchar_t tchar_t
#else
typedef unsigned char tchar_t
#endif

Then you can use the templates of most standard C++ functions/containers:

typedef std::basic_string<tchar_t> tstring

etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文