【问题标题】:pointer string not returning expected output指针字符串未返回预期输出
【发布时间】:2021-08-27 16:23:59
【问题描述】:
 #include <stdio.h>
    
    void revstr(char str[])
    {
        char temp;
        int size = 0;
        while(*str != '\0'){
            size++;
            str++;
        }
        for (int i = 0; i < size/2; i++)        
        {
            temp = str[i];               
            str[i] = str[size-1-i];
            str[size-1-i] = temp;
        }
        for(int i = 0; i < size; i++)
        {
            printf("%c\n", *(str+i));
        }
    }
    int main()
    {
        char str[20];
        printf("enter a string: \n");
        scanf("%s", &str);
        revstr(str);
        return 0;
    }

为什么我的 rev 字符串没有打印出它正在打印出一些垃圾值的字符串的反向。 你能指出原因吗?

【问题讨论】:

  • ***void revstr(char str[]) 不是可剪切粘贴的代码。如果您提供易于使用的代码示例,它会更加有用。

标签: c pointers reverse c-strings function-definition


【解决方案1】:

在您的代码中,您推进指针 str 以计算其长度,但之后您忘记将其重置为开头。此外,您对 scanf 的调用应该传递 str,而不是其地址。此外,如果用户输入的字符串长度超过 19 个字符,scanf 将超出 str 的末尾。试试这个:

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

void revstr(char str[])
{
    char temp;
    int size = strlen(str);
    for (int i = 0; i < size / 2; i++) {
        temp = str[i];
        str[i] = str[size - 1 - i];
        str[size - 1 - i] = temp;
    }
}

int main()
{
    char str[20];
    printf("enter a string: \n");
    fgets(str, sizeof(str), stdin);
    str[strcspn(str, "\n")] = '\0';
    revstr(str);
    printf("%s\n", str);
    return 0;
}

【讨论】:

    【解决方案2】:

    我会以另一种方式实现它:

    char *reverse(char *str)
    {
        char *wrk = str, *end = str;
    
        if(str && *str)
        {
            while(*(end + 1)) end++;
            while(end > wrk)
            {
                char tmp = *end;
                *end-- = *wrk;
                *wrk++ = tmp;
            }   
        }
        return str;
    }
    
    1. 最好检查一下参数是否正确。
    2. 我会返回值。它允许您在表达式中使用反转字符串并作为函数参数。示例如下:
    int main(void)
    {
        char s[] = "Hello world";
    
        printf("%s\n", reverse(s));
    }
    

    https://godbolt.org/z/fbo4nsn38

    【讨论】:

      【解决方案3】:

      在这个while循环之后

          while(*str != '\0'){
              size++;
              str++;
          }
      

      指针str不指向字符串的开头。

      相反,你可以写例如

          while( str[size] != '\0'){
              size++;
          }
      

      尽管如此,这样的函数应该只做一件事:反转字符串。是函数的调用者决定是否输出反转的字符串。

      所以函数看起来像

      char * revstr( char s[] )
      {
          size_t n = 0;
      
          while ( s[n] ) ++n;
      
          for ( size_t i = 0; i < n / 2; i++ )
          {
              char c = s[i];
              s[i] = s[n - i - 1];
              s[n - i - 1] = c;
          }
      
          return s; 
      }
      

      主要你可以写

      puts( revstr( str ) );
      

      这是一个演示程序。

      #include <stdio.h>
      
      char * revstr( char s[] )
      {
          size_t n = 0;
      
          while ( s[n] ) ++n;
      
          for ( size_t i = 0; 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 s[] = "Hello";
          
          puts( s );
          puts( revstr( s ) );
          
          return 0;
      }
      

      程序输出是

      Hello
      olleH
      

      当然,您可以使用标准字符串函数 strlen 来代替 while 循环。

      size_t n = strlen( s );
      

      scanf的调用中注意

      scanf("%s", &str);
      

      第二个参数应该是表达式str

      scanf("%s", str);
      

      【讨论】:

      • in scanf("%s", &str) 也可以正常工作,这没有问题。问题出在 while 循环中,我在其中更改了 str 的地址。谢谢你的回答
      • @nabeelkhan 如果某些东西按预期工作,但它没有,意味着它是正确的。
      • @nabeelkhan 在我的函数中,while 这个词有错别字。我更新了代码。
      • @nabeelkhan scanf("%s", &amp;str) 绝对不起作用。当您执行echo 'this is a relatively long string' | ./a.out 时会发生什么? (提示,行为未定义)。你想要if( scanf("%19s", str) == 1 ){ ... }
      • 无论您使用&amp;str 还是str,我想这都是个人喜好问题,但str 绝对是首选。最终,代码会被修改,str 会被分配到堆上,突然&amp;str 的所有用法都会出错。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 2020-02-08
      相关资源
      最近更新 更多