0

I would like to copy reversed char* to the another char*. I miss one letter in the second line of the output.

I did:

#include <iostream>

using namespace std;

void cp(char *str2, char *str1){
    char *pom1 = str1;
    while(*pom1){
        pom1++;
    }
    char* pom2 = str2;
    while(*pom1 != *str1){
         pom1--;
        *pom2 = *pom1;
         pom2++;
    }
    *pom2 = '\0';
}

int main()
{
    char *str1 = "ppC", str2[10] = "Witaj";
    cout << "Napis str2 "<< str2 << endl;
    cp(str2,str1);
    cout << "Napis str2 "<< str2 << endl;
    cp(str2,"CJP");
    cout << "Napis str2 "<< str2 << endl;
    return 0;
}

and the output is:

Napis str2 Witaj
Napis str2 Cp
Napis str2 PJC

While it should be:

Napis str2 Witaj
Napis str2 Cpp
Napis str2 PJC
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Yoda
  • 17,363
  • 67
  • 204
  • 344

4 Answers4

4

The bug is in this statement of the function

while(*pom1 != *str1){

There must be

while( pom1 != str1){

Take into account that string literals have type of constant arrays. So for example variable str1 has to be declared as

const char *str1 = "ppC";

Also the function should be declared as

void cp( char *str2, const char *str1 );

Also It will be useful to know that there is standard algorithm std::reverse_copy declared in header <algorithm>:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • @riv You are wrong. String literals in C++ have types of constant arrays. – Vlad from Moscow Mar 22 '14 at 16:50
  • `char* a = "aa";` compiles just fine. – riv Mar 22 '14 at 16:52
  • 2
    @riv It is totally unimportant whether a compiler compiles this statement. It does not influense on the type of string literals according to the C++ Standard. – Vlad from Moscow Mar 22 '14 at 16:53
  • Okay so be it, but you used their constness as an argument to why "str1 has to be declared as const", when every compiler will let it by (and doing otherwise would break backward compatibility). – riv Mar 22 '14 at 16:55
  • @riv not every compiler will let it by, obviously! – sehe Mar 22 '14 at 16:56
  • Well mine did (VS2010) :3 This is somewhat related: http://stackoverflow.com/questions/3075049/why-do-compilers-allow-string-literals-not-to-be-const Also `VirtualProtect` allows bypassing the constness if you need it for some wicked reason, so its mostly a limitation imposed by the OS. – riv Mar 22 '14 at 16:57
  • 1
    @riv str1 must have qualifier const because it is its type according to the standard. . There is no any "backward compatibility". – Vlad from Moscow Mar 22 '14 at 16:59
  • Actually `char* a = "aa";` will compiler with warnings at certain warning lavel. Make it `const` if you want to silence it. – The Mask Mar 22 '14 at 17:48
  • @TheMask: Depends on the compiler. It will not compile by Standard. And it should not compile. – Puppy Mar 22 '14 at 20:14
  • @TheMask: In C++03, yes, because it was deprecated. However, in C++11, the conversion was entirely removed and your compiler should produce an _error_, then refuse to build. Yes, this _does_ break backward compatibility with earlier C++ versions, and that's why it was deprecated first. – Lightness Races in Orbit Mar 22 '14 at 20:14
  • /cc @riv Truth above ^ – Lightness Races in Orbit Mar 22 '14 at 20:15
  • @LightnessRacesinOrbit: But about `const` will still works in C++11 or it's should produce error too? – The Mask Mar 22 '14 at 20:17
  • @TheMask: I'm sorry? I don't understand your question. – Lightness Races in Orbit Mar 22 '14 at 20:17
  • @LightnessRacesinOrbit: My bad. I mean, Will `const char *a = "a";` produce an error in C++11? – The Mask Mar 22 '14 at 20:31
  • so far I know, there's a difference from `char *a = "a";` because in the previously example compiler (such as clang) didn't produce warning – The Mask Mar 22 '14 at 20:32
  • 1
    @TheMask: No, because `const char* a = "a";` is the _correct_ way to do it. – Lightness Races in Orbit Mar 22 '14 at 20:45
2

There's reverse_copy in the stdlib

... and that it's used like:

template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
    auto f = src, l = src + std::strlen(src);
    assert(std::distance(f,l) < Ndest);
    *(std::reverse_copy(f, l, dest)) = '\0';
}

So, see it Live On Coliru

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cassert>

template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
    auto f = src, l = src + std::strlen(src);
    assert(std::distance(f,l) < Ndest);
    *(std::reverse_copy(f, l, dest)) = '\0';
}

#include <iostream>

int main()
{
    char str1[]   = "ppC";
    char str2[10] = "Witaj";

    std::cout << "Napis str2 "<< str2 << std::endl;
    cp(str2, str1);
    std::cout << "Napis str2 "<< str2 << std::endl;
    cp(str2,"CJP");
    std::cout << "Napis str2 "<< str2 << std::endl;
    return 0;
}
sehe
  • 374,641
  • 47
  • 450
  • 633
0

Just use the Standard Library, std::reverse_copy() in this case:

std::reverse_copy( input , input + strlen( input ) , output );
Manu343726
  • 13,969
  • 4
  • 40
  • 75
0

copy paste solution

int len(const char *p) {
    int c = 0;
    while (*p != '\0')
    {
        c++;
        p++;
    }
    return(c);
}

void cp(char *str2, const char *str1){
if(!(len(str2)<len(str1))){
   const char *pom1 = str1;

    while(*pom1){
        pom1++;
    }
    char* pom2 = str2;
   while( pom1 != str1){
         pom1--;
        *pom2 = *pom1;
         pom2++;
    }
    *pom2 = '\0';
}
}