使用三个指针反转字符串中的单词?

时间:2017-11-19 12:07:12

标签: c arrays string algorithm pointers

我试图在一个字符串中反转单词并且我相信我已经编写了正确的逻辑,但是在调试时我发现我在new_array char指针变量中放入的值正在丢失?我似乎不知道为什么?

你能告诉我我在做什么,怎么做才能纠正它?

#include <stdio.h>

void reverse_words(char *arr, int size) {
    char *ptr = arr;
    char *new_array = (char*)malloc(sizeof(char*) * size);

    while (*ptr != '\0') {
        ptr++;
    }
    ptr--;

    for (int i = size - 1; i >= 0; i--) {
        if (*ptr != ' ') {
            ptr--;
        } else {
            char *temp = ptr;
            temp++;
            //
            // Problem is in this block new_array value is lost when i increment it                                
            while (*temp != ' ' && *temp != '\0') {
                *new_array = *temp;
                new_array++;
                temp++;
            }
            if (i != 0) {
                *new_array = *ptr;
                ptr--;
            }
        }
    }
    *new_array = '\0';
    strcpy(arr, new_array);
    return;
}

int main() {
    char arr[] = "My job is coding";
    int size = sizeof(arr);
    reverse_words(arr, size);
    printf("%s", arr);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

您的代码太复杂,有几个问题:

  • 您分配了太多内存:(char*)malloc(sizeof(char*) * size);分配size倍于指针大小的内容。使用malloc(size);分配size个字节。
  • 指针操作中存在错误,
  • 你忘记释放已分配的内存,导致内存泄漏。
  • 您不需要传递数组的大小,通过扫描空终止符来计算字符串的长度,只需为空终止符分配一个额外的字节。

有一种替代解决方案可以在没有内存分配的情况下将字符串转换为字符串:

  • 对于每个单词,颠倒单词
  • 最后一步:反转字符串

以下是使用效用函数的代码:

#include <stdio.h>

void reverse_mem(char *str, int size) {
    for (int i = 0, j = size; i < --j; i++) {
        char c = str[i];
        str[i] = str[j];
        str[j] = c;
    }
}

void reverse_words(char *arr) {
     for (int i = 0, j = 0;; i = j) {
        for (; str[i] == ' '; i++)
            continue;
        if (str[i] == '\0')
            break;
        for (j = i; str[j] != '\0' && str[j] != ' '; j++)
            continue;
        reverse_mem(str + i, j - i);
    }
    reverse_mem(str, size);
}

int main(void) {
    char arr[] = "My job is coding";
    reverse_words(arr);
    printf("%s\n", arr);
    return 0;
}

答案 1 :(得分:0)

由于此声明,您没有按预期获得输出。

*new_array = *temp; //2nd time new_array is not pointing previous location  so how will you retrieve data 
   new_array++;// you lost previous data bcz pointers no longer holds previous address

当主循环失败时,new_array指针将指向last但它应该保存起始地址。而不是直接递增new_array,而不是

* (new_array + j) =  *temp

我将您的代码修改为。 。

void reverse_words(char *arr,int size)
{
        char * ptr = arr;
        char *new_array = (char*)malloc(sizeof(char*) * size);
        printf("initial : %u \n",ptr);
        while(*ptr != '\0')
        {
                ptr++;
        }
        int j=0;
        ptr--;
        printf("first : %c : %u  \n",*ptr,ptr);
        for(int i = size-1;i >=0;i--)
        {
                if(*ptr != ' ' ) //&& i!=0)
                {
                        ptr--;//from last to back

                }
                else
                {
                        char * temp = ptr;
                        temp++;
                        while(*temp != '\0' && *temp!=' ')
                        {
                                new_array[j++]=*temp;
                                temp++;

                        }
                        if(i!=0)
                        {
                                new_array[j++] = *ptr;
                                ptr--;
                        }
                }

        }
        new_array[j] = '\0';
        printf("new = %s \n",new_array);
        strcpy(arr,new_array);

}

我希望你找到它出错的地方,修改first字的条件,因为一旦i变为0,你就没有为此写任何逻辑。

我的解决方案根据您的要求

void reverse_words(char *arr,int size) {
        char *new_array = malloc(size * sizeof(char));
        int i,j,k=0;
        for(i = size-1 ;i >= -1 ; i--) {
                if(arr[i] ==' ' || i == -1)
                {
                        for(j=i+1;arr[j]!=' ' && arr[j]!='\0'; j++)
                                new_array[k++] = arr[j];
                        new_array[k++] = ' ';
                }
        }
        new_array[k] = '\0';
        strcpy(arr,new_array);
}