从头开始用C语言反转一个字符串

问题描述 投票:0回答:1

我正试图用C语言为一个学校项目反转一个字符串数组。这是我的代码。

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

void reverse(char * str) {
  char * p1 = str;
  int len = strlen(str) - 1;
  char temp;
  int m;

  for (m=0; m<(len/2); m++){
      temp = str[len];
      str[len]= str[m];
      str[m]=temp;
      len=len-1;
  }
  return;
}                                                                                                          

int main(void) {
  char str0[] = "";
  char str1[] = "123";
  char str2[] = "abcd";
  char str3[] = "Captain's log, Stardate 42523.7";
  char str4[] = "Hello, my name is Inigo Montoya.";
  char str5[] = "You can be my wingman anyday!";
  char str6[] = "Executor Selendis! Unleash the full power of your forces! There may be no tomorrow!";
  char * array[] = {str0, str1, str2, str3, str4, str5, str6};
  for (int i = 0; i < 7; i++) {
    reverse(array[i]);
    printf("%s\n", array[i]);
  }
  return EXIT_SUCCESS;
}

我写了逆向函数,问题是当我编译和运行代码时,它给所有字符串到str3[]的预期结果。问题是当我编译并运行这段代码时,它给出了所有字符串到str3[]的预期结果。但是在那之后,它把顺序搞乱了。下面是输出结果

321
dbca
7.32524 etlog, Starda s'niatpaC
.ayotnoM oname is Inig ym ,olleH
!yadyna ne my wingmab nac uoY
!worromot on eb yam erehT !the full power of your forces hsaelnU !sidneleS rotucexE

我不知道为什么它对一些字符串有效,但在其他字符串失败。任何帮助将是非常感激的。

c
1个回答
3
投票

另一种方法是有两个变量(如 leftright.

left 是递增和 right 是递减的,只要。left < right

这里有两种方法 一种使用索引变量。另一种使用指针变量。

#include <string.h>

void
reverse_byidx(char *str)
{
    int left = 0;
    int right = strlen(str) - 1;
    char temp;

    for (;  left < right;  ++left, --right) {
        temp = str[left];
        str[left] = str[right];
        str[right] = temp;
    }
}

void
reverse_byptr(char *str)
{
    char *left = str;
    char *right = &str[strlen(str) - 1];
    char temp;

    for (;  left < right;  ++left, --right) {
        temp = *left;
        *left = *right;
        *right = temp;
    }
}

1
投票

在你身上 for 循环,你用 len/2 作为边界条件,但您也可以修改 len 循环中,这意味着你最终会在你应该停止循环之前停止循环。

要解决这个问题其实很简单 -- 把循环条件改为:

for (m=0; m<len; m++){

或者,复制一个 len 并将其减去。

for (m=0, e=len; m<(len/2); m++, e--){
  temp = str[e];
  str[e]= str[m];
  str[m]=temp;

}


1
投票

首先,变量 len 在循环中被改变

for (m=0; m<(len/2); m++){
    //...
    len=len-1;
}

因此,条件 m<(len/2 中的变量也在改变。

但是,如果你将引入一个中间变量作为循环中右侧元素的索引,而不是使用变量 len 正如其他答案中所建议的那样,在任何情况下,这个循环都是无效的。

你的函数的问题是 reverse 在这种情况下,您将变量 len

int len = strlen(str) - 1;

循环前

for (m=0; m<(len/2); m++){

因此,例如,如果传递的字符串长度等于 4 那么这个循环应该是这样的

for (m=0; m < 2; m++){

即字符串中的元素,索引为 01 将与字符串中的元素进行交换,其索引为 32 相应的。

然而,在将变量 len 现在的循环会像

for (m=0; m < 1; m++){

因为 3 / 2 产量 1.

例如,如果你将尝试反转字符串 "ab" 产量相同

ab

因为字符串的长度等于 2 而长度减去1就等于1,所以条件是 m<(len/2) 将等同于 m < 0 而循环将不会被执行。

所以对于长度为偶数的字符串,你会得到不正确的结果。

请注意,不要使用类型为 int 用于存储字符串长度的对象,你应该使用类型 size_t. 它是函数 strlen 有。此外,一般来说,类型为 int 无法持有一个类型为 size_t 对于大字符串来说,你的函数有一个缺点,就是无法正确处理大字符串。所以你的函数有一个缺点,就是无法正确处理非常大的字符串。

另外,不要使用魔法数字,例如 7. 而不是尝试使用命名常量。

因此,函数反向可以如下所示

char * reverse( char *s )
{
    for ( size_t i = 0, n = strlen( s ); i < n / 2; i++ )
    {
        char c = s[i];
        s[i] = s[n-i-1];
        s[n-i-1] = c;
    }

    return s;
}

要输出一个反转的字符串,你可以在main中写,比如说

puts( reverse( array[i] ) );

下面是一个演示程序。

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

char * reverse( char *s )
{
    for ( size_t i = 0, n = strlen( s ); i < n / 2; i++ )
    {
        char c = s[i];
        s[i] = s[n-i-1];
        s[n-i-1] = c;
    }

    return s;
}

int main(void) 
{
    char str0[] = "";
    char str1[] = "123";
    char str2[] = "abcd";
    char str3[] = "Captain's log, Stardate 42523.7";
    char str4[] = "Hello, my name is Inigo Montoya.";
    char str5[] = "You can be my wingman anyday!";
    char str6[] = "Executor Selendis! Unleash the full power of your forces! There may be no tomorrow!";
    char * array[] = { str0, str1, str2, str3, str4, str5, str6 };

    const size_t N = sizeof( array ) / sizeof( *array );

    for ( size_t i = 0; i < N; i++ ) 
    {
        puts( reverse( array[i] ) );
    }

    return EXIT_SUCCESS;
}

它的输出是

321
dcba
7.32524 etadratS ,gol s'niatpaC
.ayotnoM oginI si eman ym ,olleH
!yadyna namgniw ym eb nac uoY
!worromot on eb yam erehT !secrof ruoy fo rewop lluf eht hsaelnU !sidneleS rotucexE

如果你想使用指针而不是下标操作符来实现函数,那么函数可以看起来像

char * reverse( char *s )
{
    if ( *s )    // check that the passed string is not empty
    {
        for ( char *first = s, *last = s + strlen( s ); first < --last; ++first )
        {
            char c = *first;
            *first = *last;
            *last = c;
        }
    }       

    return s;
}

1
投票

您修改 len 变量,所以它不再保留字符串长度。相反,你可以使用下面的代码。

 for (m = 0; m < (len + 1) / 2; m++) {
     temp = str[len - m]; // m symbol from end
     str[len - m] = str[m];
     str[m] = temp;
 }

0
投票

把它改成这样:

  // here we add a back variable
  // so that we don't modify the len variable on which the for loop
  // depends, now back will be our index at the last character
  int back = len;

  for (m=0; m<(len/2); ++m){
      temp = str[back];
      str[back]= str[m];
      str[m]=temp;
      --back;
  }
© www.soinside.com 2019 - 2024. All rights reserved.