请帮我在C中查看此代码的字符串反转?

时间:2015-04-03 09:59:54

标签: c string

我正在编写此代码以反转字符串,但不知何故,最后printf()似乎无法打印出更新字符串。我想知道原因。

#include <stdio.h>

int main() {
    char x[] = "abcdefghijklmn";
    int j = sizeof(x);
    int i = 0;
    char t = 'a';
    printf("%s,%i\n", x, j / 2);

    for (; i < j / 2; i++) {
        t = x[i];
        x[i] = x[j - i - 1];
        x[j - i - 1] = t;
        printf("%c,%i,%i\n", x[i], i, j - i - 1);
    }

    printf("%s\n", x);

    return 0;
}
sizeof()和strlen()之间的区别,也是是一种更简单的方法来反转你的字符串。检查并留下您的评论。

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

void StringReverse(char *s) {
        int i = 0;
        int j = strlen(s) - 1;
        printf("sizeof:%i,strlen:%i\n",sizeof(s),strlen(s));
        for (; i < j + 1; i++)
            printf("%c", s[j - i]);
    }

int main() {
    char x[] = "abcdefghijklmn";
    printf("sizeof:%i,strlen:%i\n",sizeof(x),strlen(x));
    StringReverse(x);

    return 0;
}

结果是:

sizeof:15,strlen:14
sizeof:4,strlen:14
nmlkjihgfedcba

然后检查一下:

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

void StringReverse(char *s) {
        int i = 0;
        int j = strlen(s) - 1;
        printf("sizeof:%i,strlen:%i\n",sizeof(s),strlen(s));
        for (; i < j + 1; i++)
            printf("%c", s[j - i]);
    }

int main() {
    char x[100];
    puts("Input a tring to reverse:");
    fgets(x,100,stdin);

    printf("sizeof:%i,strlen:%i\n",sizeof(x),strlen(x));
    StringReverse(x);

    return 0;
}

结果是:

Input a tring to reverse:
abcdefghijklmn
sizeof:100,strlen:15
sizeof:4,strlen:15

nmlkjihgfedcba

现在很清楚,strlen()总是尝试给出字符串的实际长度,但为什么第一个长度是14,第二个输入方式是15?

sizeof()由您放入char x []的数字定义,始终包含EOS;

并且指针变量为字符串,sizeof()总是返回指针长度而不是字符串长度。

【感谢@David C. Rankin】你的代码提醒我,数组变量总是被用作传递给函数的指针,因此无论你是什么,原始字符串总是保存使用常用功能(下面的第一个代码)或指向功能的指针(下面的第二个代码)。正确的吗?

第一

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

    void StringReverse(char *s) {
                int i = 0;
                int j = strlen(s);
                printf("sizeof:%i,strlen:%i\n",sizeof(s),strlen(s));

                char t = 'a';
                    for (; i < j / 2; i++) {
                        t = s[i];
                        s[i] = s[j - i - 1];
                        s[j - i - 1] = t;
                    }

                printf("%s\n", s);
            }

        int main() {
            char x[]="abcdefghijklmn";

/* if you instead write char *x="abcdefghijklmn"; here 
the compiler will encounter error, because a pointer to 
a 【string literal】 can not be used to modify the string.
*/ 
            printf("sizeof:%i,strlen:%i\n",sizeof(x),strlen(x));
            StringReverse(x);
            printf("\n%s\n", x);  //original string x is not preserved.
            return 0;
        }

结果是:

sizeof:15,strlen:14
sizeof:4,strlen:14
nmlkjihgfedcba

nmlkjihgfedcba

第二

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

char *StringReverse(char *s) {
    int i = 0;
    int j = strlen(s);
    printf("sizeof:%i,strlrn:%i\n", sizeof(s), strlen(s));

    char t = 'a';
    for (; i < j / 2; i++) {
        t = s[i];
        s[i] = s[j - i - 2];
        s[j - i - 2] = t;
    }

    return s;
}

int main() {
    char x[100];
    puts("Input a tring to reverse:");
    fgets(x, 100, stdin);

    printf("sizeof:%i,strlrn:%i\n", sizeof(x), strlen(x));
    StringReverse(x);

    printf("\n%s\n", x);  //original string x is not preserved.

    return 0;
}

结果是:

Input a tring to reverse:
abcdefghijklmn
sizeof:100,strlrn:15
sizeof:4,strlrn:15

nmlkjihgfedcba

因此,如果您想保留原始字符串,则必须使用其他方式:

......继续

6 个答案:

答案 0 :(得分:1)

李,我很高兴你喜欢这个项目。通过花时间真正理解看似简单的任务中涉及的基本指针,字符和内存操作,您可以学到很多东西。我喜欢看你的最终版本。这里还有一些供您消化和比较的内容。看看你是否可以弄清楚每个人的正确用法:

无效版

(提示:将指针传递给要反转的字符范围的开头和结尾字符)

/** strreverse - reverse string given by begin and end pointers.
 *  Takes valid string and swaps src & dest each iteration.
 *  The original string is not preserved.
 *  If str is not valid, no action taken.
 */
void strreverse (char *begin, char *end)
{
    char tmp;

    if (!begin || !end) {
        printf ("%s() Error: invalid begin or end\n", __func__);
        return;
    }

    while (end > begin)
    {
        tmp = *end;
        *end-- = *begin;
        *begin++ = tmp;
    }
}

修改原始

char*版本
/** strrevstr - reverse string, swaps src & dest each iteration.
 *  Takes valid string and reverses, original is not preserved.
 *  If str is valid, returns pointer to str, NULL otherwise.
 */
char *strrevstr (char *str)
{
    if (!str) {
        printf ("%s() Error: invalid string\n", __func__);
        return NULL;
    }

    char *begin = str;
    char *end = str + strlen (str) - 1;
    char tmp;

    while (end > begin)
    {
        tmp = *end;
        *end-- = *begin;
        *begin++ = tmp;
    }

    return str;
}

保留(复制)原始

char*版本
/** strrevdup - reverse duplicate string, swaps src & dest each iteration.
 *  Takes valid string, duplicates and reverses, original is preserved.
 *  Returns pointer to reversed string on success, NULL otherwise.
 *  Requires string.h, caller is responsible for freeing memory allocated.
 */
char *strrevdup (char* str)
{
    if (!str) {
        printf ("%s() Error: invalid string\n", __func__);
        return NULL;
    }

    char *rstr = strdup (str);
    char *begin = rstr;
    char *end = rstr + strlen (rstr) - 1;
    char tmp;

    while (end > begin){
        tmp=*end;
        *end-- = *begin;
        *begin++ = tmp;
    }

    return rstr;
}

答案 1 :(得分:0)

代码中的问题是使用sizeof()运算符。你的使用方式

int j = sizeof(x);
在这种情况下,

不正确。你想要的是利用strlen()头文件中的string.h函数。

案例1:

sizeof()运算符返回数据类型的 size x是一个char的数组,当使用字符串文字"abcdefghijklmn"初始化时,它需要15 char s。 [14个字母+ 1个终止空。]来存储值。

因此,sizeof(x)将返回15

案例2:

OTOH,strlen()不计算终止空值,因此strlen(x)将返回14

接下来,如我们所知,C中的数组索引为0-based,这意味着由n元素组成的数组将具有从0到{{{ 1}}。

因此,在情况1中,在使用值n-1时,我们引用了终止空值,它将被复制并放入j-1索引,基本上标记结束的字符串。因此,在将反向数组打印为字符串时,第一个元素beinh null标记字符串的结尾,并且不输出任何内容。

OTOH&LT;在案例2中,使用值0,我们指的是数组j-1中存在的最后一个 alphanbetic char值,它将被复制到第x个索引。复制将以这种方式继续,并且我们将按步调颠倒字符串。

答案 2 :(得分:0)

只需更改此行

即可
int j = sizeof(x);

int j = sizeof(x)-1;

由于sizeof(x)将返回15(14个数组字符和1个空字符) 数组索引从0到13的位置。

i=0;j为15。

x[i] = x[j - i - 1]; //x[0] = x[15-0-1]; i.e x[14] which is NULL.

由于x[14]是空字符,分配给x[0] 因此,在打印字符串时,它首先在字符串终止处获得空字符,这就是为什么它不提供任何输出。

我总是希望使用strlen来获取字符串的长度,因为它不包含空字符 在第二个想法中你也可以使用

int j = strlen(x);  // this will return 14.

使用&#34; string.h&#34;头文件使用此功能。

答案 3 :(得分:0)

尝试打印相反的字符串:

for (i = 1; i < sizeof(x); i++) 
    printf("%c", x[i]);

而不是:

 printf("%s\n", x);

答案 4 :(得分:0)

数组的最后一个字符是&#39; \ 0&#39;,无法反转

#include <stdio.h>

int main() {
    char x[] = "abcdefghijklmn";
    int j = sizeof(x);
    int i = 0;
    char t = 'a';
    printf("%s,%i\n", x, j / 2);

    for (; i < j / 2; i++) {
        t = x[i];
        x[i] = x[j - i - 2];
        x[j - i - 2] = t;
        printf("%c,%i,%i\n", x[i], i, j - i - 2);
    }

    printf("%s\n", x);

    return 0;
}

答案 5 :(得分:0)

sizeof()将返回带有null终止字节的值。它会导致循环运行一次迭代。

所以改成这样,

int j=sizeof(x)-1;

或者使用strlen功能。

包含头文件#include<string.h>

int j=strlen(x);