开发者

Can't print a string in reverse order in C

I have written this simple program to print a string in reverse order but it is showing segmentation fault.

#include<stdio.h>
#include<string.h>
int main (int argc, char **argv)
{
        char *string;
        int n;
        printf("Enter a string\n");
        scanf("%s",string);
        printf("\n开发者_开发问答");
        n = strlen(string);
        printf("%d",n);
        while(n != 0)
        {
                printf("%c",string[n]);
                n--;
        }
        return(0);
}

Can anybody explain me why I am getting this segmentation fault? Opearating system : Ubuntu , compilor : gcc


char *string creates a variable which can hold a pointer to a string, but it is not set here. So it points to a random location which, when accessed, segfaults.

To be useful, either allocate some memory and assign that to the pointer:

char *string = malloc(1000);  // big enough for string

or, do it all at once:

char string[1000];

Ideally, instead of using a hardcoded constant (like my example 1000) use a symbolic constant, or better yet, find out how long the string needs to be and then use that.


There are several problems with your code, which I highlighted:

-you don't allocate memory for the string

-you try to access an array element which is out of bounds

-you forgot to decrement n, so you'll have an infinite loop

Remember that arrays in C are 0-based.

#include<stdio.h>
#include<string.h>
int main (int argc, char **argv)
{
        char *string = malloc(100); //forgot to allocate memory
        int n;
        printf("Enter a string\n");
        scanf("%s",string);
        printf("\n");
        n = strlen(string);
        printf("%d",n);
        while(n != 0)
        {
                n--; //forgot to decrement here, so infinite loop
                     //crash was also from here, string[n] is not a valid index
                printf("%c",string[n]);
        }
        return(0);
}


%s with scanf does not allocate anything. The caller is supposed to allocate. Even if you were allocating something, since you don't know how big the string in the input stream is going to be, this is akin to doing gets, which is bad for security and stability reasons.

One of the simplest things you can do is have a pre-set constant amount of characters and use fgets:

char string[256];

if (!fgets(string, sizeof(string), stdin))
{
   // TODO: handle error
}

This puts an artificial limit to the maximum size of the string. Another approach would be to use dynamic memory. Here's just a quick example that grows the buffer as-needed.

char *buf = NULL;
size_t current_len = 0, current_alloc = 0;
int c = 0;
int should_continue = 1;

while (should_continue)
{
   // Read a character...
   c = fgetc(stdin);

   // If c is EOF or a newline, let's zero-terminate the buffer and terminate
   // the loop...
   if (c == EOF || c == '\n')
   {
      c = 0;
      should_continue = 0;
   }

   if (current_len + 1 > current_alloc)
   {
      // Need to grow the buffer.
      void *newbuf;
      size_t newsize;

      newsize = current_alloc ? current_alloc * 2 : 256;
      newbuf = realloc(buf, newsize);
      if (!newbuf) { /* TODO: handle error */ }

      current_alloc = newsize;
      buf = newbuf;
   }

   // We've ensured capacity, now add the character.
   buf[current_len++] = c;
}

// TODO: use buf as string...

// Now free since we're done
free(buf);

As for reversing a string, this is just an example of a typical "string manipulation, C-style" way of doing things:

// Reverse the string in-place...

void reverse(char *s)
{
   if (*s)
   {
      char *t = s + strlen(s) - 1;

      while (s < t)
      {
         char u = *s;
         *s++ = *t;
         *t-- = u;
      }
   }
}

With this, after reading you can do:

reverse(string);
puts(string);


Like @wallyk already said:

char* string

is actually a pointer to a character. You must allocate memory for the string using either,

malloc or calloc

so you can do something like:

char* string;
string = (char*) malloc( 50 * sizeof(char) );

which will allocate 50 characters for string. If your string is more than 50 characters, simply allocate appropriately.

Another way to do this is instead of creating a pointer, you can (not dynamically) allocate memory as follows:

char string[50]

That will also allocate 50 characters to string.


You have declared the string as char * and you didn't assign the address, so it points to the variable address.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜