在C中反转字符串以查找循环错误

时间:2017-01-31 20:31:47

标签: c c-strings

我有一个字符串数组,我试图反转数组中的每个字符串,看看该字符串是否是回文。我使用for循环来递增int i(索引)。然而,在我调用反向函数之后,i的值变得非常大,我无法弄清楚为什么会发生这种情况。

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

void revString(char *dest, const char *source);

int main() {    
    const char *strs[] = {
        "racecar",
        "radar",
        "hello",
        "world"
    };

    int i;
    char res[] = "";
    for (i = 0; i < strlen(*strs); i++) {
        printf("i is %d\n", i);
        revString(&res[0], strs[i]); //reversing string
        printf("i is now %d\n", i); 

        //comparing string and reversed string  
        if (strcmp(res, strs[i]) == 0) {
            printf("Is a palindrome");
        } else {
            printf("Not a palindrome");
        }
    }
    return 0;
}

void revString(char *dest, const char *source) {
    printf("%s\n", source);
    int len = strlen(source);
    printf("%d\n", len);
    const char *p;
    char s;
    for (p = (source + (len - 1)); p >= source; p--) {
        s = *p;
        *(dest) = s; 
        dest += 1;
    }
    *dest = '\0';
}

这是显示调用i函数之前和之后revString的值的输出。

i is 0
i is now 1667588961
Illegal instruction: 4

2 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题:

  • 您传递的目标数组char res[] = "";对于要反转的字符串来说太小了。它的大小为1。这会导致缓冲区溢出,从而导致未定义的行为。

    改为使用char res[20];

  • 您枚举上限不正确的字符串数组。请改用:

    for (i = 0; i < sizeof(strs) / sizeof(*strs); i++)
    
  • revString()中循环的终止测试也是错误的:当等于p时递减source具有未定义的行为,尽管不太可能产生后果。您可以通过以下方式简化此功能:

    void revString(char *dest, const char *source) {
        size_t len = strlen(source);
        for (size_t i = 0; i < len; i++) {
            dest[i] = source[len - i - 1];
        }
        dest[len] = '\0';
    }
    

以下是生成的代码:

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

void revString(char *dest, const char *source) {
    size_t len = strlen(source);
    for (size_t i = 0; i < len; i++) {
        dest[i] = source[len - i - 1];
    }
    dest[len] = '\0';
}

int main(void) {
    const char *strs[] = { "racecar", "radar", "hello", "world" };
    char res[20];

    for (size_t i = 0; i < sizeof(strs) / sizeof(*strs); i++) {
        revString(res, strs[i]);
        //comparing string and reversed string  
        if (strcmp(res, strs[i]) == 0) {
            printf("Is a palindrome\n");
        } else {
            printf("Not a palindrome\n");
        }
    }
    return 0;
}

答案 1 :(得分:0)

这是最终代码,但有一些变化

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

void revString(char* dest, const char* source);
int main(){
    const char* strs[] = {
        "racecar",
        "radar",
        "hello",
        "world"
    };

    static int i;
    char res[] = "";
    int length = (int) sizeof(strs)/sizeof(char*);
    for(i = 0; i < length; i++)
    {
        printf("i is %d\n", i);
        revString(&res[0], strs[i]); //reversing string
        printf("i is now %d\n", i);

        //comparing string and reversed string
        if(strcmp(res, strs[i]) == 0){
            printf("Is a palindrome");
        }else{
            printf("Not a palindrome");
        }
    }
    return 0;
}
void revString(char* dest, const char* source){
    printf("%s\n", source);
    int len = (int) strlen(source);
    printf("%d\n", len);
    const char* p;
    char s;
    for(p = (source + (len - 1)); p >= source; p--){
        s = *p;
        *(dest) = s; 
        dest += 1;
    }
    *dest = '\0';

}

更改1: -

  

int i; to static int i; (原因: - 我是你正在调用的本地变量   函数调用时函数调用i的值将删除后   它将分配垃圾值。)

更改2: -

  

strlen(* strs)到数组的长度(因为strlen(* strs)会给出   第一个字符串的长度)