9
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'.

And Xcode is spitting out an warning at the line: string a = "a\sb" : Unknown escape sequence

Edit: I have already tried using "a\\sb", it reads in as "a\\sb" as literal.

bames53
  • 79,748
  • 13
  • 162
  • 229
monkeyMoo
  • 145
  • 1
  • 1
  • 6
  • 3
    http://en.cppreference.com/w/cpp/language/escape. Your other option is a raw string literal, but unless you're writing a regex or something, it's a bit overkill. – chris Aug 24 '12 at 05:12
  • 1
    "a\\sb" should work fine. please post details on the problem you saw with it. – bames53 Sep 06 '12 at 14:41

2 Answers2

17
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.

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

EDIT: Xcode is behaving abnormally on your machine. So I can suggest you this.

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.

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.

EDIT 3: Edit 1 is your optimal answer here, but here's another one.

Add code in your stringMatch() method to replace double backslashes with single backslash.

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 3 is ObjectiveC and thus is not optimal, so another option in 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.

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:

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.

P.S. You have all the answers now, so it's upto you which one you implement that gives you the best results.

JVApen
  • 10,085
  • 3
  • 26
  • 56
Derpy Derp
  • 279
  • 1
  • 4
  • 12
  • 1
    There's no need to use string literal concatenation here; "a\x5Csb" would work. Also, re: EDIT2, where are you seeing the extra backslash? Is it in the debugger? Because I believe the Xcode debugger displays the strings escaped. So the correct string containing a single backslash should appear with two in the debugger. This will be true whether you initialize the string as "a\\sb" or "a\x5csb". Print it to the console to see the actual contents. – bames53 Aug 24 '12 at 20:15
  • That's the point, printing to the console strips away the extra backslash. re: Edit2 -no I didn't see it in the debugger, it is a conclusion based on my test cases. @bames53 – Derpy Derp Aug 24 '12 at 20:22
  • 1
    I think something must be wrong with your test cases. Printing to the console does not strip extra backslashes from a string. If a backslash does not appear in a string printed to the console then it's not in the string. `string a = "a\\sb"; assert(a[0] == 'a'); assert(a[1] == '\\'); assert(a[2] == 's');` – bames53 Aug 24 '12 at 20:32
  • I can assure you, there's nothing wrong with my test cases. The code you just typed deals with the `string` on a `character` level, so this way, the methods won't see the extra backslash and the console would obviously show `a\sb`. @bames53 – Derpy Derp Aug 24 '12 at 20:39
  • Yes, I look at the string at a character level to determine that only one character is a slash. There is no second slash character. What tests do you have that show that there is a second slash character in the string? – bames53 Aug 24 '12 at 20:53
  • I have many, but the relevant one that will convince you is this: open Xcode, write code to compare these two strings, `string a = "a" "\\" "sb";` & `string b = "a\\sb"`. Get back to me with your conclusions. @bames53 – Derpy Derp Aug 24 '12 at 20:58
  • Another one for your apatite: Try compiling a code with `string a = "\"` and then with, `string a = "\\"`. And then compare the `string a` with `string b = "\x5C"`. @bames53 – Derpy Derp Aug 24 '12 at 21:05
  • `"a" "\\" "sb"` and `"a\\sb"` produce the same strings. `"\"` results in a compiler warning `missing terminating '"' character`. `"\\"` and `"\x5C"` produce the same strings again. – bames53 Aug 24 '12 at 21:15
  • Are you using Xcode? If yes, I'm a little confused because of the varying behavior of Xcode. What OP is saying coincides with my results, and what you are saying is otherwise. @bames53 – Derpy Derp Aug 24 '12 at 21:22
  • I'm using clang, the compiler that Xcode uses behind the scenes. I can retry these tests with Xcode 4.4 later. – bames53 Aug 24 '12 at 21:27
  • I get the same results in Xcode 4.4. See a [screenshot](https://dl.dropbox.com/u/7511537/Post%20Content/Screen%20Shot%202012-08-24%20at%207.09.16%20PM.png). Also I remembered wrong about the debugger, it doesn't show the strings with escapes, so that can't be the reason for the confusion. – bames53 Aug 24 '12 at 23:21
  • I have tried the above code that you two have compared. I got the same result as bames53, they are displayed in the debug console with only 1 \, but somehow when it is passed into a function as an argument, it is switched back to \\ as literal... – monkeyMoo Aug 25 '12 at 05:36
  • And I agree with what Derpy Derp has said, when you pass "a\\b" to display on console, I see a\b; however when I pass into a function it is still a\\b, but what can be some ways to solve it?? – monkeyMoo Aug 25 '12 at 05:37
  • Strange, @bames53. look at my [screenshot](https://dl.dropbox.com/u/90690956/Screen%20Shot%202012-08-24%20at%2001.15.53%20AM.png). – Derpy Derp Aug 25 '12 at 06:17
  • @YatingSheng, you should use the **Edit 1** answer. – Derpy Derp Aug 25 '12 at 06:19
  • @DerpyDerp I'm pretty sure you just [photoshopped](https://dl.dropbox.com/u/7511537/Post%20Content/Photoshop%20evidence.gif) that screenshot. You got the kerning between the slashes a bit wrong. I don't know what the point of that was. (that gif should be animated, but for some reason it's not working in my browser. You may have to download it to see it flip back and forth between the photoshopped image and an actual screenshot showing the correct kerning between two slashes.) – bames53 Aug 25 '12 at 07:16
  • Here are the two images that make up the animation: [A](https://dl.dropbox.com/u/7511537/Post%20Content/Fake.png) [B](https://dl.dropbox.com/u/7511537/Post%20Content/Real.png) – bames53 Aug 25 '12 at 07:32
  • I didn't photoshop it, though I used my image optimization engine to rescale it to small dimensions. This is the unoptimized image as you can see and it is rescaled to small dimensions using photoshop: [screenshot](https://dl.dropbox.com/u/90690956/Screen%20Shot%202012-09-24%20at%2001.15.53-AM_2.png) @bames53 – Derpy Derp Aug 25 '12 at 08:30
  • It's also interesting that you seem to have customized your Xcode fonts and colors in exactly the same way I have. – bames53 Aug 25 '12 at 22:33
  • it's a coincidence @bames53, let's take a moment to breathe in and admire that........done? good. :) – Derpy Derp Aug 26 '12 at 05:46
  • You're providing incorrect information and lying to back it up. I don't understand why. – bames53 Aug 26 '12 at 06:17
  • I don't know why you think I'm lying, and my information is incorrect? Look at my answer..read it thoroughly, point out where I provided incorrect information. @bames53 – Derpy Derp Aug 26 '12 at 11:53
  • The incorrect information you're providing is that Xcode deals with backslashes differently somehow from other C++ implementations. Also you're providing a bad solution that involves Objective-C for some reason. – bames53 Aug 26 '12 at 12:42
  • I explained how I know you're lying; the screenshot you posted is clearly the result of photoshopping, obvious from the incorrect kerning (and the explanation that this is the result of an 'image optimization engine' is laughable), and the fact that the image is otherwise exactly the same as my own despite the fact that I've customized the appearance of Xcode (an _incredible_ coincidence, as in ,it does not have credibility). – bames53 Aug 26 '12 at 12:42
  • You pretend you know Xcode C/C++, but your own words make you look foolish. You say my information -"Xcode deals with backslashes differently somehow from other C++ implementations"-, is incorrect? Tell me why other C/C++ compilers don't pass strings literally with escaped backslashes. When I ran this on Visual Studio C++, strings passed b/w methods didn't dealt with the escaped backslash literally. And I can say this with absolute surety, no other vastly used C/C++ compiler deals with `strings` this way. So either my information is correct and you're wrong or this is mars, @bames53 – Derpy Derp Aug 26 '12 at 14:03
  • I've explained why you see kerning in the image, you understand my reason? No? Ever build your own image optimization engine? No? No wonder about your abilities to point out an image is photoshopped, sherlock. "and the fact that the image is otherwise exactly the same as my own" - says the guy who pointed out the difference as kerning. How can something like that be a fact? You know definition of a fact? I don't doubt that you don't know the definition, I just would like to point out you're using it incorrectly. And lastly, glad you laughed, atleast I amused you. @bames53 – Derpy Derp Aug 26 '12 at 14:24
  • "Also you're providing a bad solution that involves Objective-C for some reason." - sherlock, the more you speak, the more you seem to be a noob. Try replacing a substring of a string with another string. Try it. Xcode C++ doesn't provides a native way for search and replace which you'd known if you weren't such a noob. @bames53 – Derpy Derp Aug 26 '12 at 14:33
  • You can use the normal C++ string replace operation. For example: `string a = "abcd"; a.replace(a.find("bc"), 2, "...");` – bames53 Aug 26 '12 at 15:36
  • "Tell me why other C/C++ compilers don't pass strings literally with escaped backslashes." Xcode doesn't deal with backslashes differently. Your 'screenshot' showing that it does is a lie. – bames53 Aug 26 '12 at 15:38
  • "I've explained why you see kerning in the image" Your explanation was ridiculous. – bames53 Aug 26 '12 at 15:40
  • "Xcode doesn't deal with backslashes differently." - oh yeah? So we're definitely on mars. @bames53 – Derpy Derp Aug 26 '12 at 15:53
  • "Your explanation was ridiculous" - calling it ridiculous without having any idea about my explanation, is, ridiculous. @bames53 – Derpy Derp Aug 26 '12 at 15:54
  • Search on the internet, regarding how Xcode deals with escaped backslashes, you'll find so many posts of miserable souls. @bames53 – Derpy Derp Aug 26 '12 at 15:56
  • congrats @bames, you have internet still you lack the skill of searching for something simple on google :) – Derpy Derp Aug 26 '12 at 16:15
  • and I must add @bames53, there is some ignorance involved too. – Derpy Derp Aug 26 '12 at 16:23
8

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".

Escaping the backslash like "a\\sb" is the correct solution. If this somehow didn't work for you please post more details on that.

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:

4 a\sb

If you get different output please post it. Also please post exactly what problem you observed when you tried "a\\sb" earlier.


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)".

bames53
  • 79,748
  • 13
  • 162
  • 229