在c中交换字符串

Swap string in c

我有一个小问题,我不能交换我的字符串我有错误总线,我只能在函数 ft_strrev 时使用。我想是因为我的弦停不下来。 泰

#include <stdio.h>

char *ft_strrev(char *str)
{
    int i;
    int a;
    int temp;

    i = 0;
    a = 0;

    while(str[a] != '[=10=]')
    {
        a++;
    }

    printf ("%i\n", a);

    while(i < a  / 2 && a < 0)
    {
        temp = str[a - i - 1];
        str[a - i - 1] = str[i];
        str[i]= temp;
        i++;
        printf ("%c\n", str[i]);
    }
    return (str);
}

int main()
{
    printf("TestString");
    printf("%s", ft_strrev("TestString"));
    return (0);
}

你有 2 个主要错误。

第一个在while-loop 应该是a > 0 你编码了a < 0 .

其次通过调用 ft_strrev("TestString") 你传递一个 字符串常量 你不能 edit.This 将导致 Segmentation Fault 。所以你需要动态地为此分配内存。

解决方案:-

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

char *ft_strrev(char *st)
{
    int i;
    int a;
    char temp, *str;

    str = (char *)malloc(sizeof(st)); // allocating memory.
    strcpy(str, st);                  // copying string.
    i = 0;
    a = 0;

    while (str[a] != '[=10=]')
    {
        a++;
    }

    printf("%i\n", a);

    while (i < a / 2 && a > 0) // not a < 0
    {
        temp = str[a - i - 1];
        str[a - i - 1] = str[i];
        str[i] = temp;
        i++;
        printf("%c\n", str[i]);
    }
    return (str);
}
int main()
{
    printf("TestString");
    printf("%s", ft_strrev("TestString"));
    return (0);
}

输出:-

TestString10
e
s
t
S
S
gnirtStseT

i'can't swap my string i have error bus....

您在问题中发布的程序无法给出 总线错误 因为 while 函数中的循环条件 ft_strrev()

while(i < a  / 2 && a < 0) 
                    ^^^^^

变量 a 假设包含输入字符串 "TestString" 的大小,即 10 并且 10 < 0 将始终 return false.因此,控制永远不会进入 while 循环,您在其中尝试修改 str 同时反转作为字符串文字的输入字符串。

以下答案基于以下假设:您在发布有问题的程序时打错了字,正确的条件是 a > 0 而不是 a < 0

您的程序有一个 undefined behavior 因为您正试图修改字符串文字。您正在将字符串文字传递给函数 ft_strrev():

printf("%s", ft_strrev("TestString"));  // here "TestString" is a string literal

并且在函数 ft_strrev() 中反转输入字符串时,在 while 循环块中您试图修改输入字符串。

一个未定义的行为包括程序可能无法编译,或者它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能偶然地完全按照程序员的意图去做。

要解决此问题,您可以动态分配内存并将字符串文字复制到该内存并反转它。在这里,您需要在完成动态分配的内存后释放它。

另一个解决方案是从字符串文字初始化一个数组,如下所示:

int main() {
    char arr[] = "TestString"; // initializing array with string literal
    printf("%s\n", arr);
    printf("%s\n", ft_strrev(arr));
    return 0;
}

声明

char arr[] = "TestString";

等同于

char arr[] = {'T','e','s','t','S','t','r','i','n','g','[=14=]'};

此外,您不需要为数组提供维度。基于初始化器,编译器会自动设置维度。

这个数组arr是一个本地数组,你可以根据你的逻辑修改它的值来反转字符串。

因此,不要将字符串文字直接传递给 ft_strrev() 函数,而是在 main() [与我上面演示的相同] 中使用数组并在ft_strrev() 函数 while 循环条件

while(i < a/2 && a > 0)

尝试进行这两项更改。如果您有任何疑问,请告诉我。

虽然您不能将 字符串文字 "TestString" 传递给 ft_strrev,但在 C99+ 中,您可以传递 复合文字 ,例如(char[]){"TestString"}.

一个字符串文字,例如"TestString" 只读 内存中创建(通常在可执行文件的 .rodata 部分)任何修改只读数据的尝试都会调用 您发现的未定义行为

一个复合文字,允许转换为一个数组,该数组创建一个允许修改的数组

ft_strrev中,虽然你的循环获取字符串的长度没问题,但理解结果索引——是nul-terminating的索引字符——您稍后会在交换期间尝试通过 减法 1 遍及 strtemp 的索引来解决这个问题。在开始交换之前,只需从 a 中减去 1 就可以避免悲伤。例如,一个方便的地方是:

printf ("%i\n", a--);

有了第一个字符的索引和最后一个字符的索引,您的循环逻辑简化为:

    while (i < a) {
        ...
        i++, a--;
    }

(您也可以简单地使用指向第一个和最后一个字符的指针而不是数组索引——但这完全取决于您)

简化事情并在您的格式字符串中添加几个 '\n' 这样您的输出就不会全部混淆在一起并且您的程序符合 POSIX 标准(输出最终的 '\n'),您可以执行以下操作:

#include <stdio.h>

char *ft_strrev(char *str)
{
    int i = 0,
        a = 0;

    while (str[a])
        a++;

    printf ("%i\n", a--);

    while (i < a) {
        char temp = str[i];
        str[i] = str[a];
        str[a]= temp;
        i++, a--;
    }

    return str;
}

int main (void)
{
    printf ("TestString\n");
    printf ("%s\n", ft_strrev ((char[]){"TestString"}));

    return 0;
}

(ft_strrev开头的if (str != NULL)也要勾选)

示例Use/Output

$ ./bin/cmplitrev
TestString
10
gnirtStseT

话虽如此,虽然 复合文字 100% 好用——除非您熟悉它,否则它不是最易读的,所以您会更好服务只是在 main() 中声明一个字符数组并将该数组作为参数传递给 ft_strrev.