C字符串已反转

时间:2013-10-27 22:19:56

标签: c string

我正在编写一个简单的c程序来反转字符串,从argv [1]中获取字符串。这是代码:

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

char* flip_string(char *string){
    int i = strlen(string);
    int j = 0;

    // Doesn't really matter all I wanted was the same size string for temp.
    char* temp = string;
    puts("This is the original string");
    puts(string);
    puts("This is the \"temp\" string");
    puts(temp);

    for(i; i>=0; i--){
        temp[j] = string[i]
        if (j <= strlen(string)) {
            j++;
        }
    }

    return(temp);
}

int main(int argc, char *argv[]){
    puts(flip_string(argv[1]));
    printf("This is the end of the program\n");
}

基本上就是这样,程序编译并且所有内容都不会返回最后的临时字符串(只是空格)。在开始时,当它等于字符串时,它会打印temp。此外,如果我在for循环中使用temp的字符printf字符,则打印正确的临时字符串,即字符串 - &gt;逆转。就在我尝试将其打印到标准输出时(在for循环之后/或在主循环中)没有任何反应只打印空白区域。

感谢

3 个答案:

答案 0 :(得分:5)

你正朝着正确的方向试图使用指针。再多想一想,你可能会有它。安全实施如下:

#include <stdio.h>

char *flip_string(char *str)
{
    char *lhs = str, *rhs = str;
    if (!str || !*str || !*(str+1))
        return str;

    while (*++rhs); // rhs to eos
    while (lhs < --rhs)
    {
        char tmp = *lhs;
        *lhs++ = *rhs;
        *rhs = tmp;
    }
    return str;
}

int main()
{
    char test1[] = "Hello, World!";
    char test2[] = "";
    char test3[] = "1";
    printf("%s, %s, %s\n", flip_string(test1), flip_string(test2), flip_string(test3));
    return 0;
}

<强>输出

!dlroW ,olleH, , 1

希望它有所帮助。

答案 1 :(得分:3)

您的函数似乎执行'就地反转',即它替换了内存中的给定字符串。执行此操作时,请确保将尾随零移动到前面。这是函数的简单实现

#include <assert.h>
#include <string.h>

void flip_string(char *s)
{
    assert(s);
    char *t = strchr(s, '\0') - 1;
    for (; s < t; ++s, --t) {
        char tmp = *s;
        *s = *t;
        *t = tmp;
    }
}

该函数断言它获取一个字符串(即不是空指针)并且该内存是可写的。然后它设置一个t指针指向字符串的最后一个字符 - 通过strchr执行此操作而不是编写手动循环,这样做的好处是strchr通常是一个高度优化的函数它不以单字节步骤遍历字符串,而是一次考虑四个甚至更多字节。它也可以说更具表现力。

主循环然后交换st引用的字符(即最初是第一个和最后一个字符),然后向前/向后移动指针直到它们相遇。

该函数更简洁,因为它不需要保留传入的原始指针,而是可以直接修改s。这是决定一个函数 修改其参数返回一个新值 - 而不是两者兼而有之的结果。两者都意味着您可以像

一样调用函数
printf("%s", flip_string(s));

......这完全模糊了s实际被修改。

flip_string(s);
printf("%s", s);

在这方面更明确。

答案 2 :(得分:2)

在这里,您显然希望temp成为string以外的其他变量。但是你做的初始化会导致两个指针指向同一个位置。

你应该做的是:

char *flip_string(const char *string)
{
    char *tmp = NULL;
    size_t len = strlen(string);
    int i = 0;
    /*
     * Don't forget that strlen() returns the length of the string
     * **WITHOUT** counting the ending '\0' character.
     * Thus, you have to add the extra space when you're allocating
     */
    if (!(tmp = malloc(len + 1))) {
        printf("Allocation failed ...\n");
        return NULL;
    }
    /*
     * The newly created string must have an ending character
     * Which is '\0'
     */

    tmp[len] = '\0';

    /*
     * Here, you want to reverse the "true content" of your string.
     * That is why you ignore the ending '\0' of the string by
     * setting the upper bound to strlen (with a strict '<') **AND**
     * it is also the reason a '- 1' just pops in the index choice.
     */
    for(i = 0; i < len; i++) {
        tmp[i] = string[len - i - 1];
    }
    return tmp;
}

正如WhozCraig强调的那样,有一种替代解决方案,它只需修改参数字符串而无需分配内存:

void flip_string(char *s)
{
    size_t len = strlen(s);
    char *p = s + len - 1;
    while (s < p) {
        *p ^= *s;
        *s ^= *p;
        *p ^= *s;
        p--;
        s++;
    }
}

请注意XOR技巧,以避免为交换字符使用临时存储变量(^是{strong> C 中的XOR运算符)