-1

EDIT 04/19/2014:

Thanks every one, it finally worked thanks to your answers. I'll leave my original post bellow, in case an other beginner ends up on this topic, he could learn from my mistakes. Again, thanks for your time, and sorry I couldn't thank you sooner, but I was in no condition. See you around.

ORIGINAL POST:

I'm trying to learn how to code, but let just say that I'm far from a master level ( - so far! - ).

I got a bunch of PDF with lots of exercices in order to practice programming, and of course, I'm stuck on one of them.

I have to make a "ft_strrev", that would reverse a string. Here's what I did so far:

#include <unistd.h>

void            ft_putchar(char c)
{
        write (1, &c, 1);
}

void            ft_putstr(char *str)
{
        int     i;
        i = 0;

        while (str[i] != '\0')
        {
                ft_putchar(str[i]);
                i++;
        }
}

int             ft_strlen(char *str)
{
        int     i;
        i = 0;

        while (str[i] != '\0')
        {
                i++;
        }
        return(i);
}

void            ft_strrev(char *str)
{
        int     i;
        int     j;
        char    *str2;

        i = 0;
        j = ft_strlen(str);
        str2 = str;

        while (j != 0)
        {
                str[i] = str2[j];
                i++;
                j--;

        }
        ft_putstr(str);

}

int             main()
{
        ft_strrev("yolo");
        return(0);
}

Sorry if your eyes are bleeding or something =)

So I get a segfault, and I tried many times now to change things but it wont help. I'd like to understand why and how I should fix that.

Thanks already, sorry for my poor English skills.


Edit (I don't know if I'm supposed to delete my previous message);

Thanks a lot every one. So, with your help, I tried to change alot of things. Here's what I have now:

ft_putchar(char c);
ft_putstr(char *str);
ft_serlen(char *str);

void            ft_swap(char *a, char *b)
{
        char    tmp;

        tmp = *a;
        *a = *b;
        *b = tmp;
}

void            ft_strrev(char *str)
{
        int     i;
        int     j;

        i = 0;
        j = ft_strlen(str) - 1;

        while (i < j/2)
        {
                ft_swap(str[i], str[j]);
                i++;
        }
        ft_putstr(str);


}

int             main()
{
        char    *str;
        str = "abcd\0";

        ft_strrev(str);
        return(0);
}

As a result, gcc tells me:

$ gcc -Wall -Werror -Wextra ft_strrev.c
ft_strrev.c: In function ‘ft_strrev’:
ft_strrev.c:51:3: erreur: passing argument 1 of ‘ft_swap’ makes pointer from integer  without a cast [-Werror]
   ft_swap(str[i], str[j]);
   ^
ft_strrev.c:32:7: note: expected ‘char *’ but argument is of type ‘char’
 void  ft_swap(char *a, char *b)
       ^
ft_strrev.c:51:3: erreur: passing argument 2 of ‘ft_swap’ makes pointer from integer   without a cast [-Werror]
   ft_swap(str[i], str[j]);
   ^
ft_strrev.c:32:7: note: expected ‘char *’ but argument is of type ‘char’
 void  ft_swap(char *a, char *b)
       ^

So it's not that I don't want to try to find out why it doesnt work by myself, but I have already had this issue with other exercices and I never found how I was supposed to fix it, as the many answers to that issue I found on the internet didnt help. And I don't think I'll go far in C programming if this remained unfixed. I know this must be a stupid as it looks, but I might need your help on this one as well please (and then I'll leave you alone, I swear).

Komott
  • 17
  • 1
  • 7
  • 1
    You are trying to change the string constant. and `ft_strrev` wrong logic. – BLUEPIXY Apr 16 '14 at 10:01
  • Thanks alot, I'm doing the exercice all over again. Thank you for your help. The worst part about the string constant is that I knew it. – Komott Apr 16 '14 at 17:36

4 Answers4

0

You cannot modify a string literal such as "yolo", it's to be considered constant.

You can work around this by using an array:

char text[] = "yolo";

ft_strrev(text);

I also question the logic/algorithm used in your ft_strrev(), it doesn't swap the characters from the front and back, instead it simply copies characters from the back to the front. That will not lead to a reversal. The very first copying it does sets the 0th character to the terminator, creating a string of length 0.

unwind
  • 391,730
  • 64
  • 469
  • 606
0

Literal strings are read-only.
You are attempting to change the literal string "yolo".

Make a copy of it inside the function or copy to an array

int main(void) {
    char notreadonly[] = "yolo";
    ft_strrev(notreadonly);
    return 0;
}
pmg
  • 106,608
  • 13
  • 126
  • 198
0
void            ft_strrev(char *str)
{
        int     i;
        int     j;

        i = 0;
        j = ft_strlen(str) - 1;

        while (i < j)
        {
                ft_swap(&str[i++], &str[j--]);
        }
        ft_putstr(str);


}

int             main()
{
        char    str[] = "abcd";

        ft_strrev(str);
        return(0);
}

char *str;
str = "yolo";
char other_str[ft_strlen(str)+1];
ft_strcpy(other_str, str);
ft_strrev(other_str);
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • Works! Thanks alot! Is there a way to declare "char str[] = "abcd" " like I did for my other variables? Because the norm I have to follow forbids me to write for instance "int i = 0", I have to do it on two different lines (one for "int i;" and then "i = 0"). I tried to do it with str but I got error messages, so I don't know if it applies to strings - if you tell me there's no way to do so then I guess it doesnt apply - . – Komott Apr 16 '14 at 18:53
  • @Komott ; And then copy it to the reserved area if you are assigned to a variable of another. E.g added sample. – BLUEPIXY Apr 16 '14 at 19:38
0

Firstly, as has been suggested by @pmg and @unwind earlier, you are trying to modify a string literal, which cannot be modified; you might want to have a look at Difference between char *str="STRING" and char str[] = "STRING"?.

Secondly, in ft_strrev(), the logic for reversal is flawed; it does not actually reverse the string and the following call is erroneous:-

ft_swap(str[i], str[j]); /* A char is being passed when a char* is expected */

You can change it to something like:- while (i < j/2) {
ft_swap(&str[i], &str[j-i]); i++; }

Community
  • 1
  • 1
Phalgun
  • 1,181
  • 2
  • 15
  • 42