重新定义“int str_find(char*,char*)”错误

gblwokeq  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(118)

我正在尝试运行以下代码:
主C文件:

#include <stdio.h>
#include "my_functions.c"
#include "my_functions.h"

int main(int argv, char **argc) {
    for (int i = 0; i < argv; i++)
        printf("%s\n", argc[i]);
    printf("%d\n", str_find("=", "-h=123"));
    printf("%d\n", str_find("xyx", "aaaa"));
    return 0;
}

字符串
本地库/my_functions. c文件中包含的主**.c**文件的.c文件

#include <stdio.h>

#include "my_functions.h"

int str_length(char *mystring) {

    int i = 0;

    while (*mystring != '\0') {

        i++;

        mystring++;
    }

    return i;
}


本地Library/my_functions.h文件中的Main .c文件包含的.h文件

#ifndef MyFunctions_h
#define MyFunctions_h
#include <stdio.h>

void str_copy(char *destination, char *source) {
    while (*source != '\0') {
        *destination = *source; 
        source++; 
        destination++;
    }
    *destination = '\0';
}

#endif

int str_find(char *needle, char *haystack) {
    int i = 0;
    int c = 0;
    while (*needle != '\0') {
        ++i;
        ++needle;
    }

    needle -= i;

    while (*haystack != '\0') {
        ++c;
        ++haystack;
    }

    haystack -= c;

    int k = 0;
    int sp = 0;
   
    for (int d = 0; d <= c; ++d, ++haystack)
    {
        if (*haystack == *needle && k == 0)
        {
            sp = d;
            ++k;
            ++needle;
        } else if (*haystack != *needle && k != 0)
        {
            needle -= k;
            k = 0;
        }
    }
    
    if (sp == 0) {
        return -1;
    } else {
        return sp;
    }
}


下面是我在Visual Studio代码中的输出中收到的错误,它来自导入的my_functions.h文件和int str_find(char *needle, char *haystack)函数:

redefinition of 'int str_find(char*, char*)'


我无法自己解决这个问题,需要帮助。
需要做些什么来解决这个问题,使我的代码可以正常运行?

idfiyjo8

idfiyjo81#

问题是你没有保护str_find的定义。
main.c包括my_functions.cmy_functions.c包括my_functions.h,因此定义为str_find
之后,再次包含定义str_findmy_functions.h
要解决这个问题,只需将#endif移动到my_functions.h的底部

ioekq8ef

ioekq8ef2#

函数str_find()需要重新定义,因为它是在my_functions.h中定义的,而my_functions.hmain.c文件中包含了两次,一次是直接通过#include "my_functions.h",另一次是间接通过#include "my_functions.c"
不应该将函数 definitions 放在头文件my_functions.h中。头文件中应该只有函数 prototypes 以及结构、类型和宏定义。函数 definitions 属于my_functions.c,它正确地包含my_functions.h以进行一致性检查。
关于main.c源文件:您应该

  • 或者只包含my_functions.h,并同时编译和链接main.cmy_functions.c
  • 或者像编译单个源文件那样包含my_functions.c
  • 或包含这两个,以使用my_functions.h中的函数声明编译main函数,并追加my_functions.c的内容,以允许将单个源文件编译为可执行文件,但不建议这样做。

以下是您的文件的修改版本:

my_functions.h

int str_length(char *mystring);
void str_copy(char *destination, char *source);
int str_find(char *needle, char *haystack);

字符串

my_functions.c

#include "my_functions.h"

int str_length(char *mystring) {
    int i = 0;

    while (*mystring != '\0') {
        i++;
        mystring++;
    }
    return i;
}

void str_copy(char *destination, char *source) {
    while (*source != '\0') {
        *destination = *source; 
        source++; 
        destination++;
    }
    *destination = '\0';
}

int str_find(char *needle, char *haystack) {
    int i = 0;
    int c = 0;

    while (*needle != '\0') {
        ++i;
        ++needle;
    }

    needle -= i;

    while (*haystack != '\0') {
        ++c;
        ++haystack;
    }

    haystack -= c;

    int k = 0;
    int sp = 0;
   
    for (int d = 0; d <= c; ++d, ++haystack) {
        if (*haystack == *needle && k == 0) {
            sp = d;
            ++k;
            ++needle;
        } else if (*haystack != *needle && k != 0) {
            needle -= k;
            k = 0;
        }
    }
    
    if (sp == 0) {
        return -1;
    } else {
        return sp;
    }
}

main.c

#include <stdio.h>
#include "my_functions.h"

int main(int argv, char **argc) {
    for (int i = 0; i < argv; i++) {
        printf("%s\n", argc[i]);
    }
    printf("%d\n", str_find("=", "-h=123"));
    printf("%d\n", str_find("xyx", "aaaa"));
    printf("%d\n", str_find("aab", "aaab"));
    return 0;
}

#include "my_functions.c"


还请注意这些评论:

  • 在函数中未修改的参数字符串应定义为const char *
  • str_find()的定义是假的:它会使许多简单的测试用例失败。当你在主循环中有一个完全匹配时,你应该立即返回,当匹配失败时,你应该回溯到haystack中的下一个字符。计算字符串的长度没有真实的好处,特别是needle,你在i中计算它的长度,而且从来没有使用过。

以下是修改后的版本:

int str_find(const char *needle, const char *haystack) {
    if (*needle == '\0') {
        // special case the empty needle, return the beginning of haystack
        return 0;
    }
    for (int i = 0, j = 0; haystack[i] != '\0'; i++) {
        if (haystack[i] == needle[j]) {
            j++;
            if (needle[j] == '\0') {
                // we have a match, return the offset of the first character
                return i + 1 - j;
            }
        } else {
            i -= j;  // backtrack to start of match
            j = 0;
        }
    }
    return -1;
}

相关问题