【问题标题】:Compare string and map value比较字符串和映射值
【发布时间】:2012-10-28 23:09:47
【问题描述】:

我正在尝试比较两个字符串

一个字符串是我从 istringstream 得到的普通字符串:

string command;
iss >> command;

另一个是我从地图中得到的字符串。

但它似乎不起作用。

想法是我有一个map<string, string>,价值是 转义码更改终端输出颜色。

我的main 中有一张地图,我将所有键和值放入其中 (有效,我已经测试过了)所以我将地图传递给这个函数。

我还在程序顶部定义了颜色:

#define BLACK "\033[22;30m"
#define RED "\033[22;31m"
#define GREEN "\033[22;32m"
#define BROWN "\033[22;33m"
#define BLUE "\033[22;34m"
#define PURPLE "\033[22;35m"
#define CYAN "\033[22;36m"
#define GREY "\033[22;37m"
#define DARK_GREY "\033[01;30m"
#define LIGHT_RED "\033[01;31m"
#define LIGHT_GREEN "\033[01;32m"
#define YELLOW "\033[01;33m"
#define LIGHT_BLUE "\033[01;34m"
#define LIGHT_PURPLE "\033[01;35m"
#define LIGHT_CYAN "\033[01;36m"
#define WHITE "\033[01;37m"

这是似乎不起作用并使我感到困惑的部分:

string getColor(string command, map<string, string> &m)
{
  string color;
  if((m.find(command)->second).compare(RED) == 0)
  {
    color = RED;
    return color;
  }
  // ...and so on for all the other colors
}

我会将其设为switch,但 C++ 不允许对字符串进行开关。

所以问题是,即使两个字符串相同,它也不会那样工作。

我意识到m.find() 在我们正在寻找的位置返回一个迭代器。 但是然后做m.find()-&gt;second 应该得到正确的值吗? 而且值是一个字符串,不是吗?

简而言之,我不确定为什么比较不起作用。

编辑:

好的,这是我说的配置文件:

bold           \e[0;31m 
italic         \e[0;34m
underline      \e[0;32m 
default        \e[0;37m

所以用户输入会是这样的:

(默认这是一个(粗体简单)示例。)

所以当我得到“默认”命令时,我会在我的地图中搜索该字符串,然后获取与之关联的颜色代码。

然后我将输出颜色更改为与默认关联的地图中的颜色。 然后我将输出颜色更改为地图中与“bold”关联的颜色以打印出“simple”一词,然后我将返回之前的颜色以打印出句子的其余部分。

但是因为当我这样做时:

cout << config.find("bold")->second << " hi" << endl;

它不会改变颜色,它会打印出来:

\e[0;31m 嗨

而不是改变输出颜色:/

所以我想我会做一个比较,因为像这样:

cout << RED << "hi" << endl;

将以红色打印出 hi。

【问题讨论】:

  • ewwwwwwwww 宏坏了!

标签: c++ string comparison maps


【解决方案1】:

听起来您正在尝试进行非常复杂的地图查找。这样不行吗?

    const string & getColor(string command, const map<string, string> & m)
    {
        map<string,string>::const_iterator i = m.find(command);
        return i == m.end() ? BLACK : i->second;
    }

当然,这并没有解决假定相等的字符串不比较相等的问题。我认为,您需要发布一个更完整的示例,以便我们能够回答这个问题。但是关于嵌入空字符的第一个答案是错误的。你所拥有的是嵌入的转义字符,这是完全正确的。我唯一不同的是使用 const char * RED = etc. 而不是#defines,因为变量比宏更容易处理。

编辑:似乎我在这里指的答案消失了。

Edit2:这与您尝试做的相比如何?至少对我有用:

    #include <cstdio>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <map>
    using namespace std;

    #define BLACK "\033[22;30m"
    #define RED "\033[22;31m"
    #define GREEN "\033[22;32m"

    const string & getColor(const string & command, const map<string, string> & m)
    {
        map<string,string>::const_iterator i = m.find(command);
        return i == m.end() ? BLACK : i->second;
    }

    int main() {
        map<string,string> cols;
        cols["BLACK"] = BLACK;
        cols["RED"]   = RED;
        cols["GREEN"] = GREEN;

        string line, cmd, val;
        while(getline(cin, line))
        {
            stringstream ss(line);
            if(ss >> cmd >> val && cmd == "color:")
                cout << getColor(val, cols);
            else cout << line << endl;
        }
    }

输入

This text is default color
color: RED
This text is red
color: GREEN
This text is green

应该产生指示的颜色。

Edit3:根据您的新信息,真正的问题似乎是您的配置文件包含不包含实际的转义字符,仅包含字符“\”和“e”。确保您的文件实际上包含真正的转义字符。如何生成这些因编辑器而异。在 vim 中,您可以通过 ctrl-V 后跟 escape 来输入转义。在最坏的情况下,您可以通过从您自己的 C 程序中打印它们来生成它——毕竟您已经有了定义:fprintf(conffile, "bold %s\n", BOLD)

【讨论】:

  • 有点复杂。关键是,我正在映射一个配置文件;它会告诉我命令是什么以及相应的颜色是什么。映射完成后,我会从标准输入中获取行,当指定命令时,我必须将输出颜色更改为与命令关联的颜色。但是我无法在找到命令后使用 it->second 更改颜色,因为它只是打印出字符串而不是更改颜色,这真的很奇怪。所以我需要做一个比较……但即使这样也很困难。似乎 it->second 没有给我一个字符串:/
  • 好的,我已经编辑了我的原始帖子,以提供更多关于我正在尝试做的事情的信息。
  • 我明白了。这是有道理的。我正在使用cygwin,我将不得不调查一下。这就是在分配大纲中指定配置文件的方式。这个我得问问我的导师。谢谢
  • 如果输入确实必须采用该格式,您可以搜索子字符串“\\e”并将其替换为正确的转义字符串“\e”。 IE。 string.find 和 string.replace。您可以在读取配置文件时执行此操作。
  • 感谢您的所有帮助。原来它不是将 \e 作为转义字符读取,而是两个单独的字符;正如 amaurea 所建议的那样。所以我解决了这个问题,现在它可以正常工作了。
猜你喜欢
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-31
  • 1970-01-01
  • 2016-04-27
相关资源
最近更新 更多