C++ 在字符串中使用 \ 作为文字而不是转义符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12103445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
using \ in a string as literal instead of an escape
提问by monkeyMoo
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;
}
So the problem right now is: Xcode is not reading in the '\', when I was debugging in stringMatch function, expr appears only to be 'asb' instead of the literal a\sb'.
所以现在的问题是:Xcode 没有读取 '\',当我在 stringMatch 函数中调试时,expr 似乎只是 'asb' 而不是文字 a\sb'。
And Xcode is spitting out an warning at the line: string a = "a\sb" : Unknown escape sequence
并且 Xcode 在这一行发出警告: string a = "a\sb" : Unknown escape sequence
Edit: I have already tried using "a\\sb", it reads in as "a\\sb" as literal.
编辑:我已经尝试过使用“a\\sb”,它的字面意思是“a\\sb”。
回答by Derpy Derp
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 and C++ deal with backslashes as escape sequences by default. You got to tell C to not use your backslash as an escape sequence by adding an extra backslash to your string.
默认情况下,C 和 C++ 将反斜杠作为转义序列处理。您必须通过向字符串添加额外的反斜杠来告诉 C 不要将反斜杠用作转义序列。
These are the common escape sequences:
这些是常见的转义序列:
- \a - Bell(beep)
- \b - Backspace
- \f - Formfeed
- \n - New line
- \r - Carriage Return
- \t - Horizontal Tab
- \\ - Backslash
- \' - Single Quotation Mark
- \" - Double Quatation Mark
- \ooo - Octal Representation
- \xdd - Hexadecimal Representaion
- \a - 铃(哔)
- \b - 退格
- \f - 换页
- \n - 换行
- \r - 回车
- \t - 水平制表符
- \\ - 反斜杠
- \' - 单引号
- \" - 双引号
- \ooo - 八进制表示
- \xdd - 十六进制表示
EDIT:Xcode is behaving abnormally on your machine. So I can suggest you this.
编辑: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;
}
Don't worry about the spaces in the string a
declaration, Xcode concatenates strings separated with a space.
不用担心string a
声明中的空格,Xcode 会连接用空格分隔的字符串。
EDIT 2:Indeed Xcode is reading your "a\\b"
literally, that's how it deals with escaped backslashes. When you'll output string a = "a\\sb"
to console, you'll see, a\sb
. But when you'll pass string a
between methods as argument or as a private member then it will take the extra backslash literally. You have to design your code considering this fact so that it ignores the extra backslash. It's upto you how you handle the string.
编辑 2:实际上 Xcode 正在读取您的"a\\b"
字面意思,这就是它处理转义反斜杠的方式。当您输出string a = "a\\sb"
到控制台时,您会看到a\sb
. 但是当你string a
在方法之间作为参数或私有成员传递时,它会从字面上使用额外的反斜杠。您必须考虑到这一事实来设计您的代码,以便它忽略额外的反斜杠。这取决于你如何处理字符串。
EDIT 3:Edit 1
is your optimal answer here, but here's another one.
编辑 3:Edit 1
这里是您的最佳答案,但这是另一个。
Add code in your stringMatch()
method to replace double backslashes with single backslash.
在您的stringMatch()
方法中添加代码以用单反斜杠替换双反斜杠。
You just need to add this extra line at the very start of the function:
您只需要在函数的最开始添加这一行:
expr=[expr stringByReplacingOccurrencesOfString:@"\\" withString:@"\"];
This should solve the double backslash problem.
这应该可以解决双反斜杠问题。
EDIT 4:Some people think Edit 3is ObjectiveC and thus is not optimal, so another option in ObjectiveC++.
编辑 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.
}
}
EDIT 5:If you change the const char *
in stringMatch()
to 'string` it will be less complex for you.
编辑 5:如果您将const char *
in更改stringMatch()
为 'string`,它对您来说就不那么复杂了。
expr.replace(/*size_t*/ pos1, /*size_t*/ n1, /*const string&*/ str );
EDIT 6:From C++11 on, there exists something like raw string literals
.
This means you don't have to escape, instead, you can write the following:
编辑 6:从 C++11 开始,存在类似raw string literals
. 这意味着您不必逃避,相反,您可以编写以下内容:
string a = R"raw(a\sb)raw";
Note that the raw
in the string can be replaced by any delimiter of your choosing. This for the case you want to use a sub string like )raw
in the actual string. Using these raw string literals mainly make sense when you have to escape characters a lot, like in combination with std::regex
.
请注意,raw
字符串中的 可以由您选择的任何分隔符替换。这适用于您想)raw
在实际字符串中使用子字符串的情况。当您必须大量转义字符时,使用这些原始字符串文字主要是有意义的,例如与std::regex
.
P.S. You have all the answers now, so it's upto you which one you implement that gives you the best results.
PS 现在你已经有了所有的答案,所以你可以根据自己的情况选择哪一个来获得最好的结果。
回答by bames53
Xcode is spitting out that warning because it is interpreting \s
in "a\sb" as an escape sequence, but \s
is not a valid escape sequence. It gets replaced with just s
so the string becomes "asb".
Xcode 发出该警告是因为它将\s
“a\sb”解释为转义序列,但\s
不是有效的转义序列。它被替换为只是s
让字符串变成“asb”。
Escaping the backslash like "a\\sb"
is the correct solution. If this somehow didn't work for you please post more details on that.
转义反斜杠"a\\sb"
是正确的解决方案。如果这对您不起作用,请发布更多详细信息。
Here's an example.
这是一个例子。
#include <iostream>
#include <string>
int main() {
std::string a = "a\sb";
std::cout << a.size() << ' ' << a << '\n';
}
The output of this program looks like:
该程序的输出如下所示:
If you get different output please post it. Also please post exactly what problem you observed when you tried "a\\sb" earlier.
如果你得到不同的输出,请发布它。另外请准确发布您之前尝试“a\\sb”时观察到的问题。
Regexs can be a pain in C++ because backslashes have to be escaped this way. C++11 has raw strings that don't allow any kind of escaping so that escaping the backslash is unnecessary: R"(a\sb)"
.
正则表达式在 C++ 中可能很麻烦,因为必须以这种方式转义反斜杠。C++11 具有不允许任何类型转义的原始字符串,因此不需要转义反斜杠:R"(a\sb)"
.