在C中反转字符串

在C中反转字符串,c,string,pointers,C,String,Pointers,我开发了一个反向字符串程序。我想知道是否有更好的方法来做到这一点,如果我的代码有任何潜在的问题。我希望练习C语言的一些高级功能 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; i++) { temp = str[k];

我开发了一个反向字符串程序。我想知道是否有更好的方法来做到这一点,如果我的代码有任何潜在的问题。我希望练习C语言的一些高级功能

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; i++)
    {
        temp = str[k];
        str[k] = str[i];
        str[i] = temp;
        k--;

        /* As 2 characters are changing place for each cycle of the loop
           only traverse half the array of characters */
        if(k == (len / 2))
        {
            break;
        }
    }
}
char*reverse_字符串(char*str)
{
焦炭温度;
尺寸长度=strlen(str)-1;
尺寸i;
尺寸k=透镜;
对于(i=0;i
试试这个:

reverse_string(NULL);
reverse_string("");

既然你说你想变得有趣,也许你会想用一个。

来交换你的字符。你可以把你的
(len/2)
测试放在for循环中:

for(i = 0,k=len-1 ; i < (len/2); i++,k--)
{
        temp = str[k];
        str[k] = str[i];
        str[i] = temp;

}
for(i=0,k=len-1;i<(len/2);i++,k--)
{
温度=str[k];
str[k]=str[i];
str[i]=温度;
}

我没有看到返回语句,您正在更改输入字符串,这可能会给程序员带来问题。您可能希望输入字符串是不可变的

此外,这可能很挑剔,但国际海事组织认为,len/2只应计算一次


除此之外,只要您处理rossfabricant提到的问题案例,它就会起作用。

您可以更改for循环声明以缩短代码:

char* reverse_string(char *str)
{
    char temp;
    size_t len = strlen(str) - 1;
    size_t stop = len/2;
    size_t i,k;

    for(i = 0, k = len; i < stop; i++, k--)
    {
        temp = str[k];
        str[k] = str[i];
        str[i] = temp;
    }
    return str;
}
char*reverse_字符串(char*str)
{
焦炭温度;
尺寸长度=strlen(str)-1;
停止尺寸=长度/2;
尺寸i,k;
对于(i=0,k=len;i
与其中途中断,不如缩短循环

size_t length = strlen(str);
size_t i;

for (i = 0; i < (length / 2); i++)
{
    char temp = str[length - i - 1];
    str[length - i - 1] = str[i];
    str[i] = temp;
}
size\u t length=strlen(str);
尺寸i;
对于(i=0;i<(长度/2);i++)
{
char temp=str[length-i-1];
str[length-i-1]=str[i];
str[i]=温度;
}

只是重新安排一下,然后进行安全检查。我还删除了您未使用的返回类型。我认为这是一个安全且干净的方法:

#include <stdio.h>
#include <string.h>

void reverse_string(char *str)
{
    /* skip null */
    if (str == 0)
    {
        return;
    }

    /* skip empty string */
    if (*str == 0)
    {
        return;
    }

    /* get range */
    char *start = str;
    char *end = start + strlen(str) - 1; /* -1 for \0 */
    char temp;

    /* reverse */
    while (end > start)
    {
        /* swap */
        temp = *start;
        *start = *end;
        *end = temp;

        /* move */
        ++start;
        --end;
    }
}


int main(void)
{
    char s1[] = "Reverse me!";
    char s2[] = "abc";
    char s3[] = "ab";
    char s4[] = "a";
    char s5[] = "";

    reverse_string(0);

    reverse_string(s1);
    reverse_string(s2);
    reverse_string(s3);
    reverse_string(s4);
    reverse_string(s5);

    printf("%s\n", s1);
    printf("%s\n", s2);
    printf("%s\n", s3);
    printf("%s\n", s4);
    printf("%s\n", s5);

    return 0;
}
#包括
#包括
无效反向_字符串(char*str)
{
/*跳过空值*/
如果(str==0)
{
返回;
}
/*跳过空字符串*/
如果(*str==0)
{
返回;
}
/*射程*/
char*start=str;
char*end=start+strlen(str)-1;/*-1表示\0*/
焦炭温度;
/*逆转*/
while(结束>开始)
{
/*交换*/
温度=*开始;
*开始=*结束;
*结束=温度;
/*移动*/
++开始;
--结束;
}
}
内部主(空)
{
char s1[]=“反转我!”;
字符s2[]=“abc”;
字符s3[]=“ab”;
字符s4[]=“a”;
字符s5[]=“”;
反向_字符串(0);
反向_串(s1);
反向_串(s2);
反向_串(s3);
反向_串(s4);
反向_字符串(s5);
printf(“%s\n”,s1);
printf(“%s\n”,s2);
printf(“%s\n”,s3);
printf(“%s\n”,s4);
printf(“%s\n”,s5);
返回0;
}

编辑后,当strlen为0时,end不会指向可能不正确的内存位置。

如果您想练习C的高级功能,指针如何? 我们可以扔在宏和异或交换的乐趣了

#include <string.h> // for strlen()

// reverse the given null-terminated string in place
void inplace_reverse(char * str)
{
  if (str)
  {
    char * end = str + strlen(str) - 1;

    // swap the values in the two given variables
    // XXX: fails when a and b refer to same memory location
#   define XOR_SWAP(a,b) do\
    {\
      a ^= b;\
      b ^= a;\
      a ^= b;\
    } while (0)

    // walk inwards from both ends of the string, 
    // swapping until we get to the middle
    while (str < end)
    {
      XOR_SWAP(*str, *end);
      str++;
      end--;
    }
#   undef XOR_SWAP
  }
}
请注意,每次在中使用宏参数时,它们都会显示一次 宏定义。这可能非常有用,但也可能破坏您的代码 如果使用不当。例如,如果我压缩了增量/减量 指令和宏调用到一行中,如

      XOR_SWAP(*str++, *end--);
然后这将扩展到

      do { *str++ ^= *end--; *end-- ^= *str++; *str++ ^= *end--; } while (0);
它有三倍的递增/递减操作,实际上 做应该做的交换

当我们谈到这个主题时,您应该知道异或(
^
)是什么意思。这是基本的 算术运算-像加法、减法、乘法、除法,除了 它通常不是在小学教的。它逐位组合两个整数 -喜欢加成,但我们不在乎结转<代码>1^1=0
1^0=1
0^1=1
0^0=0

一个众所周知的技巧是使用xor交换两个值。这是因为有三个基本的原因 xor的属性:
x^0=x
x^x=0
x^y=y^x
用于所有值
x
y
。假设我们有两个 最初存储两个值的变量
a
b
va
vb

因为我们
str
,在上面的代码中不会发生这种情况,所以我们没事

当我们关心正确性时,我们应该检查边缘情况。
if(str)
行应该确保没有为字符串指定
NULL
指针。空字符串
”怎么样?嗯
strlen(“”==0
,所以我们将
end
初始化为
str-1
,这意味着
while(str
条件永远不会为真,所以我们什么都不做。这是正确的

有很多C语言需要探索。玩得开心

更新:提出了一个很好的观点,那就是您必须稍微小心如何调用它,因为它确实在运行

 char stack_string[] = "This string is copied onto the stack.";
 inplace_reverse(stack_string);
这很好,因为
stack\u string
是一个数组,其内容被初始化为给定的字符串常量。然而

 char * string_literal = "This string is part of the executable.";
 inplace_reverse(string_literal);
将导致代码在运行时燃烧并消亡。这是因为
string\u literal
只指向作为可执行文件的一部分存储的字符串-通常是操作系统不允许编辑的内存。在一个更快乐的世界里,你的编译器会知道这一点,并在你试图编译时抛出一个错误,告诉你
string\u literal
必须是
char const*
类型,因为你不能修改内容。然而,这不是我的编译器生活的世界

有一些黑客,你可以尝试确保一些内存是对的 // initially: // a == va a ^= a; // now: a == va ^ va // == 0 a ^= a; // now: a == 0 ^ 0 // == 0 a ^= a; // now: a == 0 ^ 0 // == 0
 char stack_string[] = "This string is copied onto the stack.";
 inplace_reverse(stack_string);
 char * string_literal = "This string is part of the executable.";
 inplace_reverse(string_literal);
#include <stdio.h>
#include <string.h>

char *revStr (char *str) {
    char tmp, *src, *dst;
    size_t len;
    if (str != NULL)
    {
        len = strlen (str);
        if (len > 1) {
            src = str;
            dst = src + len - 1;
            while (src < dst) {
                tmp = *src;
                *src++ = *dst;
                *dst-- = tmp;
            }
        }
    }
    return str;
}

char *str[] = {"", "a", "ab", "abc", "abcd", "abcde"};

int main(int argc, char *argv[]) {
    int i;
    char s[10000];
    for (i=0; i < sizeof(str)/sizeof(str[0]); i++) {
        strcpy (s, str[i]);
        printf ("'%s' -> '%s'\n", str[i], revStr(s));
    }
    return 0;
}
'' -> ''
'a' -> 'a'
'ab' -> 'ba'
'abc' -> 'cba'
'abcd' -> 'dcba'
'abcde' -> 'edcba'
void inplace_rev( char * s ) {
  char t, *e = s + strlen(s);
  while ( --e > s ) { t = *s;*s++=*e;*e=t; }
}
void reverse(char *s)
{
  char *end,temp;
  end = s;
  while(*end != '\0'){
    end++;
  }
  end--;  //end points to last letter now
  for(;s<end;s++,end--){
    temp = *end;
    *end = *s;
    *s = temp; 
  }
}
#include <stdio.h>
#include <string.h>

int main() 
{
    char *data = "hello world";
    int length=strlen(data);
    char bytes[length];
    int n=0;
    while(n<=length)
    {
       bytes[n] = data[length-n-1];
       n++;
    }
    printf("%s\n", bytes);
    return 0;   
}
#include <stdio.h>

int main()    
{

    char string[100];
    int i;

    printf("Enter a string:\n");
    gets(string);
    printf("\n");
    for(i=strlen(string)-1;i>-1;i--)

    printf("%c",string[i]);
}
rev {
int len = strlen(str)-1;
for ( int i =0; i< len/2 ; i++ ) {
        char t = str[i];
        str[i] = str[len-i];
        str[len-i] = t;
        }

}
char *string_reverse(char *dst, const char *src)
{
    if (src == NULL) return NULL;

    const char *src_start = src;
    char *dst_end = dst + strlen(src);
    *dst_end = '\0';

    while ((*--dst_end = *src_start++)) { ; }

    return dst;
}
bool reverse_string(char* str) {
    if(str == NULL){
        return false;
    }
    if(strlen(str) < 2){
        return false;
    }
    
    char* first = str;
    char* last = str + strlen(str) - 1; // Minus 1 accounts for Index offset
    char temp;

    do{
        temp = *first;
        *first = *last;
        *last = temp;
    }
    while (++first < --last); // Update Pointer Addresses and check for equality

    return true;
}
Here is my shot which will handle all the cases 
char *p ="KDLAKDADKADAD"
char p[] = "lammdlamldaldladadada"
also empty string 

#include<stdio.h>
#include<string.h>enter code here
#include<stdlib.h>
char *string_reverse(char *p);
int main()
{

        char *p = " Deepak@klkaldkaldkakdoroorerr";
        char *temp = string_reverse(p);
        printf("%s", temp);
}
char *  string_reverse( char *p )
{

        if(*p == '\0')
        {
                printf("No charecters are present \n");
                return 0;
        }
        int count = strlen(p)+1;
        int mid = strlen(p)/2;
        char *q  = (char *)malloc(count * sizeof(char));
        if( q )
        {
                strcpy(q,p);
                char *begin,*end,temp;
                begin = q ;
                end = q+strlen(p)-1  ;
                int i = 0;
                while( i < mid/2 )
                {
                        temp = *end;
                        *end = *begin;
                        *begin = temp;
                        begin++;
                        end--;
                        i++;
                }
                return q;
        }
        else
        {

                printf("Memory Not allocated ");
        }
        free(q);
}
/* Author: Siken Dongol */
#include <stdio.h>

int strLength(char *input) {
    int i = 0;
    while(input[i++]!='\0');
    return --i;
}

int main()
{
    char input[] = "Siken Man Singh Dongol";

    int len = strLength(input);
    char output[len];

    int index = 0;
    while(len >= 0) {
        output[index++] = input[--len];
    }

    printf("%s\n",input);
    printf("%s\n",output);
    return 0;
}
void strrev(char* str) { 
    size_t len = strlen(str);
    char buf[len]; 

    for (size_t i = 0; i < len; i++) { 
        buf[i] = str[len - 1 - i]; 
    }; 

    for (size_t i = 0; i < len; i++) { 
        str[i] = buf[i]; 
    }
}
void strrev (char s[]) {

int i;
int dim = strlen (s);
char l;

for (i = 0; i < dim / 2; i++) {
    l = s[i];
    s[i] = s[dim-i-1];
    s[dim-i-1] = l;
    }

}
void revString(char *s)
{
  char *e = s; while(*e){ e++; } e--;
  while(e > s){ *s ^= *e; *e ^= *s; *s++ ^= *e--; }
}
#include <stdio.h>
#define MAX_CHARACTERS 99

int main( void );
int strlen( char __str );

int main() {
    char *str[ MAX_CHARACTERS ];
    char *new_string[ MAX_CHARACTERS ];
    int i, j;

    printf( "enter string: " );
    gets( *str );

    for( i = 0; j = ( strlen( *str ) - 1 ); i < strlen( *str ), j > -1; i++, j-- ) {
        *str[ i ] = *new_string[ j ];
    }
    printf( "Reverse string is: %s", *new_string" );
    return ( 0 );
}

int strlen( char __str[] ) {
    int count;
    for( int i = 0; __str[ i ] != '\0'; i++ ) {
         ++count;
    }
    return ( count );
}
#include <string.h>

void reverse(char *);

int main(void){
 char name[7] = "walter";
 reverse(name);
 printf("%s", name);
}

void reverse(char *s) {
  size_t len = strlen(s);
  char *a = s;
  char *b = &s[(int)len - 1];
  char tmp;
  for (; a < b; ++a, --b) {
    tmp = *a;
    *a = *b;
    *b = tmp;
  }
}
     int main()
     {
         char str[] = "This is an example";
         char *p = str + strlen(str); /* point to the end of the string */
         p--; /* points to the last char of the string */

         for (int i = 0; i < strlen(str); i++, p--)
         {
            printf("%c", *p);
         }

         return 0;
     }