无法在C中以相反的顺序打印字符串

时间:2011-09-20 17:50:14

标签: c

我编写了这个简单的程序,以相反的顺序打印字符串,但它显示了分段错误。

#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);
}

有人能解释我为什么会出现这种分段错误吗?操作系统:Ubuntu,compilor:gcc

5 个答案:

答案 0 :(得分:6)

char *string创建一个变量,可以保存指向字符串的指针,但不在此处设置。所以它指向一个随机位置,当被访问时,会发生段错误。

为了有用,要么分配一些内存并将其分配给指针:

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

或者,一次完成所有操作:

char string[1000];

理想情况下,不是使用硬编码常量(如我的示例1000)而是使用符号常量,或者更好,找出字符串需要多长时间然后使用它。

答案 1 :(得分:2)

您的代码存在一些问题,我强调了这一点:

- 你不为字符串分配内存

- 您尝试访问超出范围的数组元素

- 你忘了减少n,所以你将有一个无限循环

请记住,C中的数组是从0开始的。

#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);
}

答案 2 :(得分:2)

带有%s

scanf不会分配任何内容。调用者应该分配。即使你分配一些东西,因为你不知道输入流中的字符串有多大,这类似于做gets,这对安全性和稳定性原因。

您可以做的最简单的事情之一就是预先设定一定数量的字符并使用fgets:

char string[256];

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

这会对字符串的最大大小设置一个人为限制。另一种方法是使用动态内存。这里只是一个根据需要增加缓冲区的快速示例。

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);

至于反转字符串,这只是典型的“字符串操作,C风格”处理方式的一个例子:

// 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;
      }
   }
}

有了这个,读完后你可以这样做:

reverse(string);
puts(string);

答案 3 :(得分:0)

就像@wallyk已经说过的那样:

char* string

实际上是指向角色的指针。您必须使用

为字符串分配内存
malloc or calloc

所以你可以这样做:

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

将为字符串分配50个字符。如果您的字符串超过50个字符,只需适当分配。

另一种方法是不是创建指针,而是可以(不动态)分配内存,如下所示:

char string[50]

那也将为字符串分配50个字符。

答案 4 :(得分:-1)

您已将字符串声明为char *并且未指定地址,因此它指向变量地址。