Inefficient code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool StripBackslash1(char* buf)
{
    char* tmp = buf;
    bool ret = false;

    for(tmp = buf; *tmp != '\0'; tmp++)
    {
        if(tmp[0] == '\\' && tmp[1] == '\\')
        {
            strcpy(tmp, tmp+1);
            ret = true;
        }
   }

    return ret;
}


the code above strips backslashes but I do not understand how it is done from code, it seems to me that the code increases the address each time in the loop and copies the string from the succeeding address to the current address, how does this strip backslashes?

Last edited on
it finds it, on line 8, and when it does (the if statement is true) it copies the back half of the string over the current part.
for example:

blahblah \\ whatever
finds the \ and the \ [0] and [1]
then it copies " whatever" over the first backslash.
if it removed any, it returns true.

this is C code; c++ would use string which has a way to do this for you.
it may be more efficient to use strstr to find the pattern if you are writing C.

its not that bad. It can probably be faster, but its not 'that' inefficient. Change it for strstr and call it good, unless you are absolutely sure it is a bottleneck for performance.
Last edited on
http://www.cplusplus.com/reference/cstring/strcpy/ writes:
To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.

Likewise, https://en.cppreference.com/w/c/string/byte/strcpy writes:
The behavior is undefined if the strings overlap.


In other words: your code has undefined behaviour. It does not "work".
Last edited on
It replaces all occurrences of \\ with \. Without using strcpy(), consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

bool StripBackslash1(char *buf)
{
	bool ret {};

	for (; *buf; ++buf)
		if (*buf == '\\' && *(buf + 1) == '\\')
			for (char *p = buf + 1; *p; ++p) {
				*p = *(p + 1);
				ret = true;
			}

	return ret;
}

int main()
{
	char data[] = R"(abc\\def\\ghi)";

	std::cout << data << '\n';

	StripBackslash1(data);
	std::cout << data << '\n';
}



abc\\def\\ghi
abc\def\ghi

Last edited on
If you want to use strstr(), then:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <cstring>

bool StripBackslash1(char *buf)
{
	bool ret {};

	for (; buf = std::strstr(buf, R"(\\)"); ++buf)
		for (char* p = buf + 1; *p; ++p) {
			*p = *(p + 1);
			ret = true;
		}

	return ret;
}

int main()
{
	char data[] = R"(zxcb\\lk\\g)";

	std::cout << data << '\n';

	StripBackslash1(data);
	std::cout << data << '\n';
}



zxcb\\lk\\g
zxcb\lk\g

Last edited on
memmove is safe if you are in C and need to overlap the memory. I think most compilers work if you overlap strcpy but they are correct, it isnt ensured and is unsafe to assume.

The C library function void *memmove(void *str1, const void *str2, size_t n) copies n characters from str2 to str1, but for overlapping memory blocks, memmove() is a safer approach than memcpy().
Last edited on
Topic archived. No new replies allowed.