用于反转字符串的C代码 - 包括字符串末尾的NULL字符

时间:2015-07-21 18:51:06

标签: c string segmentation-fault reverse

1。)是否可以反转包含NULL字符的字符串 (这意味着“abcd”表示为五个字符,包括空字符。)

2。)在我目前的实施中,不考虑1.), 我在交换期间遇到分段错误。即在分配时:* str = * end;

void reverse(char *str)
    {
        char * end = str;
        char tmp;
        if (str)
        {  // to handle null string
            while (*end)
            {  // find the end character
                ++end;
            }
            --end; // last meaningful element
            while (str < end) // terminal condition: str and end meets in the middle
            {   tmp = *str; // normal swap subroutine
                *str = *end; // str advance one step
                *end = tmp;   // end back one step

                str++;
                end-- ;
            }
        }
        return;
    }

4 个答案:

答案 0 :(得分:2)

你的功能是正确的。似乎问题是你试图反转一个字符串文字。您可能无法更改字符串文字。他们是不变的。任何改变字符串文字的尝试都会导致程序的未定义行为。

来自C标准(6.4.5字符串文字)

  

7未指明这些阵列是否与它们不同   元素具有适当的值。 如果程序尝试   修改这样的数组,行为未定义

只考虑写

会更好
if ( *str )

而不是

 if (str)

或者如果你想检查poinetr是不是NULL,那么

if ( str && *str )

在这种情况下,这个减量

--end;
即使原始字符串为空,

也会有效。

然而,功能本身可以按照以下方式定义,如示范程序中所示

#include <stdio.h>

char * reverse( char *s )
{
    char *last = s;

    while ( *last ) ++last;

    if ( last != s )
    {        
        for ( char *first = s; first < --last; ++first )
        {
            char c = *first;
            *first = *last;
            *last = c;
        }
    }

    return s;
}    

int main( void )
{
    char s[] = "Hello arshdeep kaur";

    puts( s );
    puts( reverse( s ) );
}    

程序输出

Hello arshdeep kaur
ruak peedhsra olleH

答案 1 :(得分:0)

  1. 我很确定你能。你只需要字符串的长度并注意测试NUL。

  2. 字符串可以并且可能应该被视为字符数组。特别是,尝试将字符串文字指向已经初始化的字符串是一种无效操作。

  3. 一个例子:

    Here is one way to reverse a string:
    
    void reverse(char *str) {
      // First calculate the length
      unsigned int length = 0;
      int i = 0;
      for (; str[i] != '\0'; i++) {
        ++length;
      }
      ++length;
      // Allocate temporary storage
      char tmp = malloc(length);
      int x = 0;
      // Loop through starting at the end and go backwards
      // It is perfectly legal to change the characters themselves, just not the pointer
      for (i = length - 1; i >= 0; i++, x++) {
        if (str[i] != '\0') {
          tmp[x] = str[i];
        }
      }
      tmp[length - 1] = '\0';
      // Reassign to the given argument
      for (i = 0; i < length; i++) {
        str[i] = tmp[i];
      }
      // Free memory
      free(tmp);
    }
    

    与其他答案一样,您正在尝试做一些在标准中留下未定义行为的事情。

答案 2 :(得分:0)

像这样调用你的代码:

photo.py

输出:

int main()
{
    char a[]="abcd";
    int i;
    reverse(a);
    for (i=0;i<5;i++) {
        printf("a[%d]=%02x\n",i,a[i]);
    }
}

所以你可能传入一个字符串文字(即a[0]=64 a[1]=63 a[2]=62 a[3]=61 a[4]=00 )。这些文字通常存储在内存的只读部分,这可能是它的核心转储原因。

话虽如此,当您处理字符串时,执行包含空字符的反转并不是很实用。

答案 3 :(得分:0)

您可以尝试以下方法:

void reverse(char *str) {
    char *end = str;
    char tmp;
    if (str) {
        while (*end){
            ++end;
        }
        --end;
        while (str < end) {
            tmp = *str;
            *str++ = *end;
            *end-- = tmp;
        }
    }
}