繁体   English   中英

C反向字符串函数得到奇怪的输出

[英]C reverse string function getting weird output

我正在尝试理解指针并制作了反向字符串函数。
码:

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

char *reverseString(char string[]){
    int i;
    int len = strlen(string);
    char reversedString[len];  
    for (i = 0; i < len; i++){
        reversedString[i] = string[(len - 1) - i];
    }
    printf("%s", reversedString); //print it out

    return reversedString; //return pointer to first element of reversed string
}

int main (){
    char string[6] = "kitten";
    int i;
    char *p = reverseString(string);
    return (0);

}

我的目标是扭转字符串“小猫”并打印反转的字符串。 我希望输出“nettik”,但我得到“nettik ”。 为什么我会得到这些奇怪的角色?

停止! 首先,你在初学者学习指针时经常会犯一个经典的错误。 当你写:

char *reverseString(char string[]) {
    ...
    char reversedString[len];
    return reversedString;
}

你返回一个指针, 在那里,不就是:记忆,当你离开的功能,所以没有保证你觉得内存包含您的反向字符串尚未得到别的东西再利用实际上得到释放。 这样,您的程序将灾难性地失败。

但是,你打印的逆转字符串返回之前,所以它是没有大问题 那么,那里出现的问题是你的字符串没有被正确地终止。

C语言中的字符串需要空间来存储其最后的'\\0'字节: char string[6] = "kitten"; 太小而不能保持零终止字符串{ 'k', 'i', 't', 't', 'e', 'n', '\\0' } 类似地,当你调用printf("%s", reversedString) ,你还没有用'\\0'正确终止字符串,所以printf一直在查找字符串的结尾并打印出内存中的任何垃圾,其中reversedString是分配。

你应该试试:

  • 让你的函数返回void
  • 为原始字符串分配7个字节,
  • 为新字符串分配strlen(string) + 1 (也将是7)个字节,和
  • 在反向循环旧字符串之后,将'\\0'写入新字符串的末尾。

您的代码中至少存在两个主要错误。 还有更多。

首先,对strlen的调用会导致未定义的行为,因为您没有将它传递给以null结尾的字符串。 原因是你的char数组不足以容纳null终止符:

char string[6] = "kitten";

你需要

char string[7] = "kitten";

要么

char string[] = "kitten";

其次,您将返回指向本地数组的指针,即reversedString 取消引用也会导致未定义的行为。 你可以通过将字符串就地反转,或者将指针传递给与输入相同长度的缓冲区来解决这个问题。 请记住,反向字符串也必须以空值终止。

功能错了。

所有它的第一个返回指向退出函数后将被销毁的本地数组的指针

//,,,
char reversedString[len];  
//...
return reversedString; //return pointer to first element of reversed string

其次,反向串应终止为零。 但是,您声明一个没有空间用于终止零的数组。

此主数组中的此数组也定义错误

char string[6] = "kitten";

因为它不包括终止零。

最后,这是一个糟糕的功能设计。

如果要在目标字符串中复制源字符串,则应将两个字符数组声明为函数参数。 此外,源数组应声明为常量数组。

该功能可以通过以下方式查看

char *reverseCopyString( char s1[], const char s2[] )
{
    size_t n = strlen( s2 );

    for ( size_t i = 0; i < n; i++ ) s1[i] = s2[n - i - 1];
    s1[n] = '\0';

    return s1;
}

或者您可以定义函数,以便反转源字符串。 例如

char *reverseString( char s[] )
{
    size_t n = strlen( s );

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

考虑到字符串文字在C中是不可变的,可能不会被更改。 任何更改字符串文字的尝试都会导致程序的未定义行为。

这是一个示范计划

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

char *reverseCopyString( char s1[], const char s2[] )
{
    size_t n = strlen( s2 );

    for ( size_t i = 0; i < n; i++ ) s1[i] = s2[n - i - 1];
    s1[n] = '\0';

    return s1;
}

char *reverseString( char s[] )
{
    size_t n = strlen( s );

    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 *s1 = "Hello gilianzz";
    char s2[16];

    puts( s1 );
    puts( reverseCopyString( s2, s1 ) );
    puts( reverseString( s2 ) );
}    

程序输出是

Hello gilianzz
zznailig olleH
Hello gilianzz

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM