0

So it seems it works when I reversed "hello", but it prints out something weird like "ol▒eh" in the middle. It's gone when I fixed

i< length/2;

to

i<= length/2;

Isn't the first one supposed to be the right one? what's the ▒ character mean in C? is it something like Null?

void reverse_copy(char dest[], const char src[]){
  size_t i;
  char temp;
  size_t length = (size_t)strlen(src);
  for(i = 0; i <= length/2; i++){ /*?? why i<length/2 is not working*/
    dest[i] = src[length-i-1];
    temp = src[i];
    dest[length-i-1] = temp;
  }
}
4
  • 1
    Please try to create a minimal reproducible example to show us. It should include how you call it, and what you pass for the arguments. Commented Feb 11, 2019 at 8:28
  • 4
    I also recommend that you learn how to debug your programs, as that's how one usually solves problem like that. Commented Feb 11, 2019 at 8:28
  • 3
    The loop would be simpler if you traverse its full length. Going half way is usual if you are reversing a string in place (otherwise it gets reversed twice), and in this case it does not matter if you skip the central character because it remains the same. Note too, you have not null-terminated the destination string. Commented Feb 11, 2019 at 8:41
  • @Someprogrammerdude Thanks, I was in a rush. I'll try to make it better next time. Commented Feb 12, 2019 at 7:45

4 Answers 4

7

The main problem with i< length/2; is that it may leave out the "middle" element in case of odd string lenght of src. Hence, the middle element in dest may remain uninitialized, showing up as some "arbitrary" ASCII value then.

But in general, your code is appropriate for reverse_in_place, where you have to take care of not overwriting something that you need later in the loop for copying.

If you do a reverse_copy, however, it is sufficient - or better - to simply have one reverse loop:

void reverse_copy(char dest[], const char src[]){
  size_t i;
  size_t length = strlen(src);
  for(i = 0; i < length; i++){
    dest[i] = src[length-i-1];
  }
  dest[i] = '\0';
}
Sign up to request clarification or add additional context in comments.

2 Comments

By doing dest[i] = ‘\0’; , are you initializing the last index as null because that’s what the char array (string) in C supposed to have ? Like {h,e,l,l,o,’\0’} what does this line do to prevent from preventing?
I meant *crashing
3

With :

for(i = 0; i < length/2; i++){

you never set the middle character (for odd lengths) in dest.

With your example "hello", length/2 is 2, so you set (for i = 0) :

dest[0] = src[5-0-1]; // dest[0] = src[4]
dest[5-0-1] = src[0]; // dest[4] = src[0]

and then (for i = 1) :

dest[1] = src[5-1-1]; // dest[1] = src[3]
dest[5-1-1] = src[1]; // dest[3] = src[1]

and that's it. You never set dest[2].

2 Comments

NMDV, yet "...and that's it" is incorrect as OP's code also lacks `dest[length] = '\0';
@chux : the "that's it" refers to what the OP's code does. It does no more - it doesn't set dest[2], and you're right it also doesn't set dest[5]. I haven't mentioned the latter because it doesn't seem pertinent to the question (the OP asked about the character in dest[2] - presumably the dest buffer was already 0 initialized).
2

Because i<length/2 is already based on integer division, i.e: it will floor the result. This will skip the middle element in case of odd length strings.

Comments

1

To understand what is happening in the code, a debugger would help. You need to step through the code line by line and watch what is the value of i and length - i - 1.


The reason a strange character appears in the middle is that if length is odd then the middle item is skipped when the condition is <.

For example, when length == 5 then 5/2 == 2 (because of integer division 2.5 comes out to be 2 ). So analysing the loop:

  1. i=0
  2. is i < 2. Yes, so continue code block.
  3. dest[0] = src[4]
  4. temp = src[0]
  5. dest[4] = temp
  6. i++ i is 1
  7. is i < 2. Yes, so continue code block.
  8. dest[1] = src[3]
  9. temp = src[1]
  10. dest[3] = temp
  11. i++ i is 2
  12. is i < 2. No, so exit the loop

So looking at the steps (especialialy steps 3,5,8,10) only dest[0], dest[1], dest[3], dest[4] are written from the source when checking <. Destination 2 is not changed.

This problem does not arise for even numbers.


As dest[2] was not updated then the character which was already there, is been displayed. Which could be any random character. If it was initialized to 0 (a null) then that is the character that represents 0.

But looking at that character it looks more like a value 177 (extended ASCII codes :http://www.asciitable.com/)


Also I find this definition of reverse_copy very error prone, as it it doesn't know how big the destination buffer is. It can overwrite something if it is too small.


In this case I would use a sentinel to mark the end of the string, and use a while loop:

void reverse_copy(char dest[], const char src[])
{
    const char* src_end = src + strlen(src) - 1;
    --src;

    while (src_end > src)
    {
        *dest = *src_end;

        ++dest;
        --src_end;
    }
    *dest = '\0';
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.