3

I was using this SO question as part of a program that needs to reverse a string. The problem I am having is that I cannot seem to get the function to work. Here is the code I have:

int main(int argc, char *argv[]){
  char *test = "Testing";
  fputs(test, stdout);
  fputs(reverse_string(test), stdout);
}

char* reverse_string(char *str){
  char temp;
  size_t len = strlen(str) - 1;
  size_t i;
  size_t k = len;
  for(i = 0; i < (len +1)/2; i++){
    temp = str[k];
    str[k] = str[i];
    str[i] = temp;
    k--;
  }  
  return str;
}

I am getting an error that there is conflicting types for 'reverse_string'

Edit: For anyone wondering here is the code that works. See @chux's answer for an explanation.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* reverse_string(char *str){
  char temp;
  size_t len = strlen(str) - 1;
  size_t i;
  size_t k = len;
  for(i = 0; i < (len +1)/2; i++){
    temp = str[k];
    str[k] = str[i];
    str[i] = temp;
    k--;
  }
  return str;
}
int main(int argc, char *argv[]){
  char test[] = "Testing";
  fputs(test, stdout);
  fputs(reverse_string(test), stdout);
}
Community
  • 1
  • 1
Danny Dyla
  • 631
  • 4
  • 15
  • 2
    You probably need to put reverse_string above main or declare it. The compiler is probably assuming some things about the function. – NG. Jan 10 '14 at 03:31
  • If I run the same program with reverse_string declared above main I get a segmentation fault still. – Danny Dyla Jan 10 '14 at 03:50
  • 1
    @DannyDyla as chux and I mentioned in his answer, you can not modify a string literal. – Shafik Yaghmour Jan 10 '14 at 03:52

2 Answers2

6

You can not pass a const char * to a char *

char *test = "Testing";
fputs(reverse_string(test), ... // bad, attempting to change constant data.
// bad as  reverse_string() is assumed to return int, but fputs() expects char *

char* reverse_string(char *str) { // Bad, there's now a function conflict

Instead

char* reverse_string(char *str);  // Need to declare/define function first

char test[] = "Testing";
fputs(reverse_string(test), ... // good

[Edit]
You problem was well identified (missing function declaration) by others. My suggestion takes care of the next problem. In C, a missing declaration of a function will assume int reverse_string(...) which does not match char* reverse_string(char *str).

[Edit]
As @Shafik Yaghmou suggests, modifying a string literal char *test = "Testing" will result in undefined behavior. Hence the char test[] = "Testing" which initializes test with "Testing\0", but may be modified.

[Edit]
@GreenAsJade correctly points out OP's original error message is due to the assumed int reverse_string(...) supplying an int to s in int fputs(const char * s, FILE * stream);

char *test1 = "Testing" is not the same thing as char test2[] = "Testing". test1 becomes a char * with the size of a pointer. The initial pointer value is to a string "Testing" located elsewhere in memory. test2 is a char array with size 8: length of "Testing" + 1 for '\0'. The array test2 is initialized with 'T', 'e', ... '\0' etc.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    +1 you should also mention about forward declaring `reverse_string` and mentioning that modifying a string literal is undefined would be helpful. – Shafik Yaghmour Jan 10 '14 at 03:33
  • Your answer suprised me. I'm still none the wiser, because your first code block compiles fine (after you put the reverse_string(test) call inside main()). I thought the now-deleted answers about predeclaring were the correct answer! – GreenAsJade Jan 10 '14 at 03:39
  • 1
    I was under the impression that `char *test = "Testing"` is the same thing as `char test[] = "Testing"`. Is that not true? – Danny Dyla Jan 10 '14 at 03:45
  • I'm wondering the same thing. I didn't realise that c is so fussy about constness... I had thought of that as more of a C++ thing. It's a long time since I've done hands on c programming though! (which is why I like reading these!) – GreenAsJade Jan 10 '14 at 03:47
  • 2
    @DannyDyla please see my answer to [Difference between array and pointer to string literal](http://stackoverflow.com/q/20296674/1708801). – Shafik Yaghmour Jan 10 '14 at 03:50
  • @chux: It is fair to say that it is not correct to say that you can't pass a const char * to a char *, in C? I think that you can do it, you just might get a seg fault, if you try to modify it. This is a little different. One is a compile time certain error, the other a run time thing, that depends on the function body. – GreenAsJade Jan 10 '14 at 04:12
  • @ GreenAsJade Yes, your detail is closer (Type qualifiers §6.7.3 6). Note: C had a long history before `const` arrived and thus allows `char *test = "Testing"` when it should be `const char *test = "Testing"`. Had OP done so (and pre-declared the function), likely a warning about sending a `const char *` to `reverse_string(char *)` would have ensued. – chux - Reinstate Monica Jan 10 '14 at 15:20
1

FWIW:

(h2hh)momerath:Documents mgregory$ cat test.c
char* reverse_string(char *str) {
  return str;
}

char *test = "Testing";

int main() {

  reverse_string(test);
}
(h2hh)momerath:Documents mgregory$ gcc test.c
(h2hh)momerath:Documents mgregory$ 

I think that the answer to the OP's question is that reverse_string has to be declared before being used, to be not int.

GreenAsJade
  • 14,459
  • 11
  • 63
  • 98