0

help me.. why this C program doesnt reverse the string ? it crashes... but when i use a character array the code seems to work fine..but the moment i use a pointer to a string..its giving goosebumps...help me solve this..

#include<stdio.h>
#include<conio.h>
#include<string.h>

int main(){

    char *String="gokul";
    char *Begin =String;
    char *End = String + strlen(String) - 1;
    char TempChar = '\0';

    while (Begin < End)
    {
        TempChar = *Begin;
        *Begin = *End;
        *End = TempChar;
        Begin++;
        End--;
    }
    puts(String);
}
Inisheer
  • 20,376
  • 9
  • 50
  • 82
Gokul Rajan
  • 113
  • 3
  • 10
  • Why don't you use `strcmp`? –  May 10 '13 at 19:54
  • 3
    What possible use would strcmp() be? He's not comparing anything, he's trying to emulate strrev() (Which still won't work because his string string is a constant). – Lee Daniel Crocker May 10 '13 at 20:00
  • @LeeDanielCrocker: Do you know how `strcmp` works? See here: http://www.tutorialspoint.com/ansi_c/c_strcmp.htm and the OP's while loop –  May 10 '13 at 20:02
  • 1
    @0A0D I think you need coffee. `strcmp` really has nothing to do with this question. – Daniel Fischer May 10 '13 at 20:03
  • 1
    I've been programming C for 30 years, I think I know how strcmp() works. Did you even read the question? – Lee Daniel Crocker May 10 '13 at 20:03
  • 1
    Seriously, @0A0D, I think you're having a major brainfart here. His code is completely correct except for trying to change a string constant. What makes you think he's trying to compare something? – Lee Daniel Crocker May 10 '13 at 20:06
  • @LeeDanielCrocker: I could be completely off base here, but I don't think checking `Begin < End` is very reliable. –  May 10 '13 at 20:07
  • 1
    The Begin pointer is walking up, the End pointer is walking down, and the loop exits when they meet. Works perfectly. – Lee Daniel Crocker May 10 '13 at 20:08
  • @0A0D Both point into the same array, it's reliable - or even integer arithmetic isn't reliable. One exception, though, if `strlen(String) == 0`, we have a problem. – Daniel Fischer May 10 '13 at 20:08
  • @DanielFischer: At start, `Begin` is equal to `gokul` and `End` is equal to 1. Also, if `strlen` is 0.. well you know –  May 10 '13 at 20:12
  • @0A0D `Begin` points to the `g` in "gokul" and `End` points to the `l` (`String + strlen(String) - 1` -> `String + 5 - 1` -> `String + 4`)... and what's `String[4]`? It's the `l`. You're **hallucinating** . The only issue (except for the non-modifiability) *might* be with strings of 0 length. – Nik Bougalis May 10 '13 at 20:15
  • Um, no, End starts at `String + strlen(String) - 1`, which is a pointer to the last character. – Lee Daniel Crocker May 10 '13 at 20:15
  • @0A0D `strlen(String) == 0` is the _only_ problem (apart from non-modifiability). Here, a nonempty string is given, so the possibility that `End` marches off the start is theoretical. – Daniel Fischer May 10 '13 at 20:16
  • @LeeDanielCrocker: I must be imagining things then http://ideone.com/xOqM1Q –  May 10 '13 at 20:17
  • @0A0D Of course `Begin < End`, `Begin` points to the first character, `End` to the last. – Daniel Fischer May 10 '13 at 20:19
  • @0A0D Are you dense? `Begin` *SHOULD* be less than `End` at that point! `Begin` points to the start of the string and `End` to the end. What are you on? – Nik Bougalis May 10 '13 at 20:20
  • @NikBougalis: Sorry, meant `l` not `1`. I feel like we are dancing around in circles here and I will circle the wagons to return to my original argument that `strcmp` is preferred here over straight comparisons of the pointers. That's all I have to say. –  May 10 '13 at 20:24
  • `strcmp`?!? For what possible purpose would you use `strcmp`? Do you even know what `strcmp` does? The OP is trying to **REVERSE** a string and his actual reversing code (including the pointer arithmetic) is fine, with one possible exception: the case of a zero-length string. Seriously, is it troll day today? Are we being punked? – Nik Bougalis May 10 '13 at 20:26
  • 2
    @0A0D The `<` doesn't compare strings, it compares addresses. – Daniel Fischer May 10 '13 at 20:28
  • @0A0D: I can imagine some code that can use `strcmp()` instead of the pointer comparison, but it is really an ugly way to test if the loop should terminate in a string reversal implementation. – jxh May 10 '13 at 20:32
  • Actually, Nik, his code is fine for a 0-length string too, just not for a NULL one. – Lee Daniel Crocker May 10 '13 at 20:32
  • @LeeDanielCrocker No, `String - 1` invokes undefined behaviour. I can't imagine that it would actually break anywhere, but formally, it's not okay for an empty string. – Daniel Fischer May 10 '13 at 20:34
  • @LeeDanielCrocker for a zero length string, it's conceivable his code could fail *if* `String` points to the lowest addressible memory location - the `String + 0 - 1` would then likely overflow. Granted, this is unlikely to happen. NULL strings will cause an issue depending on how his implementation of `strlen` handles them and that ought to be corrected if it's important in his case. – Nik Bougalis May 10 '13 at 20:34
  • @DanielFischer : Pointing to the element before or the element after an array is perfectly acceptable in C, as long as you never dereference it. On an empty string, End will start out pointing before the string, Begin < End will be false, and all is well. – Lee Daniel Crocker May 10 '13 at 20:37
  • @LeeDanielCrocker: I am aware it is fine to point after, but I had never heard it was fine to point before. I thought this was an issue for certain segmented architectures. – jxh May 10 '13 at 20:38
  • @LeeDanielCrocker Only one past the end, not one before, cf. 6.5.6 (8). – Daniel Fischer May 10 '13 at 20:40
  • You might be right about that. The C spec says "beyond the end" of the array. I always assumed that meant either end, but that could be my misinterpretation. – Lee Daniel Crocker May 10 '13 at 20:42

1 Answers1

4

The problem is that String is pointing to a string literal, which is in read-only memory. You can still use a pointer for String, but it has to point to memory that can be modified.

char gokul[] = "gokul";
char *String = gokul;

Edit to address some minor issues.

There is no need to include the non-standard header conio.h in your program.

Your code does not handle the case where String is NULL.

Your loop is technically incorrect if String is an empty string, since End would point before the string.

main() should return a value, since it is declared to do so. 0 indicates success. Newer C compilers will know that the latest C Standard allows a program to hit the end of main() without return to mean to implicitly return a 0 for you.

#include<stdio.h>
#include<string.h>

int main(){

    char gokul[] = "gokul";    
    char *String=gokul;

    if (String && *String) {
        char *Begin =String;
        char *End = String + strlen(String) - 1;
        char TempChar = '\0';

        while (Begin < End)
        {
            TempChar = *Begin;
            *Begin = *End;
            *End = TempChar;
            Begin++;
            End--;
        }
        puts(String);
    }
    return 0;
}
jxh
  • 69,070
  • 8
  • 110
  • 193
  • That really has nothing to do with his problem and I think you missed the problem entirely. –  May 10 '13 at 19:56
  • 2
    @0A0D: How so? Poster says: works when I use an array for `String`, fails when `String` is a pointer. He/she is trying to reverse `String` in place. – jxh May 10 '13 at 19:57
  • Because its an incomplete answer and does not address the multiple problems with his program. Yes `char*` is read-only but there is more to it here. –  May 10 '13 at 19:59
  • 1
    @0A0D: Uh, "incomplete" is *way* different from "missed the problem entirely." – jxh May 10 '13 at 20:00
  • 2
    @0A0D No, that string literals mustn't be modified is really the only serious issue. – Daniel Fischer May 10 '13 at 20:01
  • 1
    @0A0D: You're hallucinating. The question is very clear, his code is absolutely correct except for trying to write a constant. – Lee Daniel Crocker May 10 '13 at 20:01
  • Yay, a downvote without a comment. – jxh May 10 '13 at 20:41
  • As a consolation for the downvote, wasn't it a beautiful trainwreck? – Daniel Fischer May 10 '13 at 20:52
  • Sorry if I caused confusion, but if it makes you feel better, I didn't downvote.. I am out of votes for a few hours –  May 10 '13 at 21:20
  • @0A0D: No worries. I am actually voting to close as duplicate. But, the duplicate's answer is also incomplete. – jxh May 10 '13 at 21:27