11
bool stringMatch(const char *expr, const char *str) {   
    // do something to compare *(expr+i) == '\\'  
    // In this case it is comparing against a backslash
    // i is some integer
}

int main() {
    string a = "a\sb";
    string b = "a b";
    cout << stringMatch(a.c_str(), b.c_str()) << endl;
    return 1;
}

所以现在的问题是:Xcode 没有读取'\',当我在 stringMatch 函数中调试时,expr 似乎只是'asb'而不是文字 a\sb'。

Xcode 在该行发出警告: string a = "a\sb" : Unknown escape sequence

编辑:我已经尝试过使用“a\\sb”,它读作“a\\sb”作为文字。

4

2 回答 2

21
bool stringMatch(const char *expr, const char *str) {   
   // do something to compare *(expr+i) == '\\'  
   // In this case it is comparing against a backslash
   // i is some integer
}

int main() {
    string a = "a\\sb";
    string b = "a b";
    cout << stringMatch(a.c_str(), b.c_str()) << endl;
    return 1;
}

默认情况下,C 和 C++ 将反斜杠作为转义序列处理。您必须通过在字符串中添加一个额外的反斜杠来告诉 C 不要使用您的反斜杠作为转义序列。

这些是常见的转义序列:

  • \a - 铃声(哔)
  • \b - 退格
  • \f - 换页
  • \n - 换行
  • \r - 回车
  • \t - 水平制表符
  • \\ - 反斜杠
  • \' - 单引号
  • \" - 双引号
  • \ooo - 八进制表示
  • \xdd - 十六进制表示

编辑: Xcode 在您的机器上表现异常。所以我可以建议你这个。

bool stringMatch(const char *expr, const char *str) {   
   // do something to compare *(expr+i) == '\\'  
   // In this case it is comparing against a backslash
   // i is some integer
}

int main() {
    string a = "a" "\x5C" "sb";
    string b = "a b";
    cout << stringMatch(a.c_str(), b.c_str()) << endl;
    return 1;
}

不用担心string a声明中的空格,Xcode 会连接用空格分隔的字符串。

编辑 2:确实 Xcode 正在阅读您的"a\\b"字面意思,这就是它处理转义反斜杠的方式。当您输出string a = "a\\sb"到控制台时,您会看到a\sb. 但是,当您将string a方法之间作为参数或私有成员传递时,它会从字面上使用额外的反斜杠。您必须考虑这个事实来设计您的代码,以便它忽略额外的反斜杠。如何处理字符串取决于您。

编辑 3: Edit 1这是您的最佳答案,但这是另一个。

在您的方法中添加代码以stringMatch()用单反斜杠替换双反斜杠。

你只需要在函数的最开始添加这个额外的行:

expr=[expr stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"];

这应该解决双反斜杠问题。

编辑 4: 有些人认为编辑 3是 ObjectiveC,因此不是最佳的,所以 ObjectiveC++ 中的另一个选项。

void searchAndReplace(std::string& value, std::string const& search,std::string const& replace)
{
    std::string::size_type  next;

    for(next = value.find(search);        // Try and find the first match
        next != std::string::npos;        // next is npos if nothing was found
        next = value.find(search,next)    // search for the next match starting after
                                          // the last match that was found.
       )
    {
        // Inside the loop. So we found a match.
        value.replace(next,search.length(),replace);   // Do the replacement.
        next += replace.length();                      // Move to just after the replace
                                                       // This is the point were we start
                                                       // the next search from. 
    }
}


编辑 5:如果您将const char *in更改stringMatch()为“字符串”,它对您来说将不那么复杂。

expr.replace(/*size_t*/ pos1, /*size_t*/ n1, /*const string&*/ str );

编辑 6:从 C++11 开始,存在类似raw string literals. 这意味着您不必逃避,相反,您可以编写以下内容:

string a = R"raw(a\sb)raw";

请注意,raw字符串中的 可以替换为您选择的任何分隔符。这适用于您想要使用)raw实际字符串中的子字符串的情况。当您必须大量转义字符时,使用这些原始字符串文字主要是有意义的,例如与std::regex.

PS你现在有了所有的答案,所以由你来决定你实施哪一个能给你带来最好的结果。

于 2012-08-24T05:19:21.113 回答
9

Xcode 吐出该警告,因为它\s在 "a\sb" 中解释为转义序列,但\s不是有效的转义序列。它被替换s为字符串变为“asb”。

像这样转义反斜杠"a\\sb"是正确的解决方案。如果这对您不起作用,请发布更多详细信息。

这是一个例子。

#include <iostream>
#include <string>

int main() {
    std::string a = "a\\sb";
    std::cout << a.size() << ' ' << a << '\n';
}

该程序的输出如下所示:

4 a\sb

如果您得到不同的输出,请发布。还请准确发布您之前尝试“a\\sb”时观察到的问题。


正则表达式在 C++ 中可能很痛苦,因为必须以这种方式转义反斜杠。C++11 的原始字符串不允许任何类型的转义,因此不需要转义反斜杠:R"(a\sb)".

于 2012-08-24T05:14:06.893 回答