简体   繁体   English

循环以反转C中的字符串

[英]loop to reverse string in C

So I've looked around on SO and can't find code that answers my question. 所以我四处查看,所以找不到能回答我问题的代码。 I have written a function that is supposed to reverse a string as input in cmd-line. 我编写了一个函数,该函数应该将字符串反转为cmd行中的输入。 Here is the function: 这是函数:

void reverse (char string[]) {
    int x;
    int i = 0;
    char line[strlen(string)];

    for (x = strlen(string) - 1; x > 0; x--) {
        char tmp = string[x];
        line[i] = tmp;
        i++;
    }
    string = line;
}

When I call my reverse() function, the string stays the same. 当我调用reverse()函数时,字符串保持不变。 ie, 'abc' remains 'abc' 即,“ abc”仍为“ abc”

If more info is needed or question is inappropriate, let me know. 如果需要更多信息或问题不适当,请告诉我。

Thanks!! 谢谢!!

You're declaring your line array one char shorter remember the null at the end. 您声明的line数组要短一个char请记住null处为null

Another point, it should be for (x = strlen(string) - 1; x >= 0; x--) since you need to copy the character at 0 . 还有一点,应该for (x = strlen(string) - 1; x >= 0; x--)因为您需要将字符复制到0

void reverse (char string[]) {
    int x;
    int i = 0;
    char line[strlen(string) + 1];

    for (x = strlen(string) - 1; x >= 0; x--) {
        char tmp = string[x];
        line[i] = tmp;
        i++;
    }

    for(x = 0; x < strlen(string); x++)
    {
        string[x] = line[x];
    }
}

Note that this function will cause an apocalypse when passed an empty string or a string literal (as Bobby Sacamano said). 请注意,此函数在传递空字符串或字符串文字时将导致启示(如Bobby Sacamano所说)。

Suggestion you can probably do: void reverse(char source[], char[] dest) and do checks if the source string is empty. 建议您可以执行以下操作: void reverse(char source[], char[] dest)并检查源字符串是否为空。

The last line in your code does nothing string = line; 代码的最后一行不执行任何操作string = line;

Parameters are passed by value, so if you change their value, that is only local to the function. 参数按值传递,因此,如果更改其值,则该值仅在函数本地。 Pointers are the value of the address of memory they are pointing to. 指针是它们所指向的内存地址的值。 If you want to modify the pointer that the function was passed, you need to take a pointer to that pointer. 如果要修改传递函数的指针,则需要使用指向该指针的指针。

Here is a short example of how you could do that. 这是一个简单的例子。

void reverse (char **string) {
    char line = malloc(strlen(*string) + 1);
    //automatic arrays are deallocated once the function ends
    //so line needs to be dynamically or statically allocated

   // do something to line

    *string = line;
}

The obvious issue with this is that you can initialize the string with static memory, then this method will replace the static memory with dynamic memory, and then you'll have to free the dynamic memory. 显而易见的问题是,您可以使用静态内存初始化字符串,然后此方法将用动态内存替换静态内存,然后必须释放动态内存。 There's nothing functionally wrong with that, it's just a bit dangerous, since accidentally freeing the string literal is illegal. 这在功能上没有什么错,只是有点危险,因为不小心释放字符串文字是非法的。

char *test = "hello";
reverse(test);
free(test); //this is pretty scary

Also, if test was allocated as dynamic memory, the pointer to it would be lost and then it would become a memory leak. 同样,如果将测试分配为动态内存,则指向它的指针将丢失,然后将成为内存泄漏。

I think that your answer is almost correct. 我认为您的答案几乎是正确的。 You don't actually need an extra slot for the null character in line. 您实际上不需要为行中的空字符添加额外的插槽。 You just need two minor changes: 您只需要进行两个小更改:

  • Change the assignment statement at the bottom of the procedure to a memcpy. 将过程底部的赋值语句更改为memcpy。
  • Change the loop condition to <- 将循环条件更改为<-

So, your correct code is this: 因此,您的正确代码是这样的:

void reverse (char string[]) {
  int x;
  int i = 0;
  char line[strlen(string)];

  for (x = strlen(string) - 1; x >= 0; x--) {
    char tmp = string[x];
    line[i] = tmp;
    i++;
  }
  memcpy(string, line, sizeof(char) * strlen(line));
}

Since you want to reverse a string, you first must decide whether you want to reverse a copy of the string, or reverse the string in-situ (in place). 由于要反转字符串,因此首先必须确定是要反转字符串的副本,还是要就地(就地)反转字符串。 Since you asked about this in 'C' context, assume you mean to change the existing string (reverse the existing string) and make a copy of the string in the calling function if you want to preserve the original. 由于您是在'C'上下文中询问此问题的,因此,假设您要保留原始字符串,则要更改现有字符串(反转现有字符串)并在调用函数中复制该字符串。

You will need the string library 您将需要字符串库

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

Array indexing works, and this version takes that approach, 数组索引有效,而该版本采用了这种方法,

/* this first version uses array indexing */
char*
streverse_a(char string[])
{
    int len; /*how big is your string*/
    int ndx; /*because 'i' is hard to search for*/
    char tmp; /*hold character to swap*/
    if(!string) return(string); /*avoid NULL*/
    if( (len=strlen(string)) < 2 ) return(string); /*one and done*/
    for( ndx=0; ndx<len/2; ndx++ ) {
        tmp=string[ndx];
        string[ndx]=string[len-1-ndx];
        string[len-1-ndx]=tmp;
    }
    return(string);
}

But you can do the same with pointers, 但是您可以对指针执行相同操作

/* this is how K&R would write the function with pointers */
char*
streverse(char* sp)
{
    int len, ndx; /*how big is your string */
    char tmp, *bp, *ep; /*pointers to begin/end, swap temporary*/
    if(!sp) return(sp); /*avoid NULL*/
    if( (len=strlen(bp=sp)) < 2 ) return(sp); /*one and done*/
    for( ep=bp+len-1; bp<ep; bp++, ep-- ) {
        tmp=*bp; *bp=*ep; *ep=tmp; /*swap*/
    }
    return(sp);
}

(No, really, the compiler does not charge less for returning void.) (不,实际上,编译器不会为返回void收取更多费用。)

And because you always test your code, 而且由于您始终会测试代码,

char s[][100] = {
    "", "A", "AB", "ABC", "ABCD", "ABCDE",
    "hello, world", "goodbye, cruel world", "pwnz0r3d", "enough"
};

int
main()
{
    /* suppose your string is declared as 'a' */
    char a[100];
    strcpy(a,"reverse string");

    /*make a copy of 'a', declared the same as a[]*/
    char b[100];
    strcpy(b,a);
    streverse_a(b);
    printf("a:%s, r:%s\n",a,b);

    /*duplicate 'a'*/
    char *rp = strdup(a);
    streverse(rp);
    printf("a:%s, r:%s\n",a,rp);
    free(rp);

    int ndx;
    for( ndx=0; ndx<10; ++ndx ) {
        /*make a copy of 's', declared the same as s[]*/
        char b[100];
        strcpy(b,s[ndx]);
        streverse_a(b);
        printf("s:%s, r:%s\n",s[ndx],b);

        /*duplicate 's'*/
        char *rp = strdup(s[ndx]);
        streverse(rp);
        printf("s:%s, r:%s\n",s[ndx],rp);
        free(rp);
    }
}

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

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