0

我使用了 string.h 库中的 strlen() 函数,但不包括我想从最初实现的头文件中包含的头文件,因为我正在编写自己的 strcpy() 实现,如果我包含它说的头文件它是 strcpy() 的多个定义。那么如何仅包含头文件中的特定定义。我需要使用 extern 关键字吗?

#include <stdio.h>
#include <stdlib.h>
#include "exercise 5.5.h"

int main() {
  char *s = "hello";
  char *t = "helli";
  int n = 3;
  if (n > strlen(t))
    printf("\nsorry the value of n is greater than the size of t");
  else {
    S = strncpy(s, t, n);
    printf("\nther is %d", x);
  }
}

标头有 strncpy 的定义

终端跟踪

exercise. 5.5_main.c:10:7: incompatible implicit declaration of built-in function "strien
exercise 5.5 main.c:10:7: note: include <string.h> or provide a declaration of 'strlen

我不想包含 string.h 但如何明确提供 strlen 的定义

标题

char* strncat(char *s, char *t, int n);
char* strncpy(char *s, char *t, int n);
int strncmp(char *s,char *t, int n);
4

1 回答 1

3

像这样重新实现标准库函数strcpy可能会很棘手。因为它是一个标准库函数,它的名字在某种意义上是“保留的”——你不应该自己使用它。(它不像关键字 like 那样被强烈保留switch,但尝试编写一个名为的函数通常仍然是一个坏主意strcpy——更不用说它通常完全没有必要的事实!)

在回答您的明确问题时,不,没有办法“选择性地包含”您自己选择的系统头文件中的声明,例如<string.h>.

如果由于某种原因您需要编写自己的版本strcpy,您有多种选择,具体取决于具体情况。

  1. 重命名您自己的函数。例如,调用它my_strcpy。(这是通常的方法。)

  2. 确保函数的定义完全正确,并且与标准头文件中的声明完全匹配。例如,如果您有strcpy(char *dst, char *src) {...}char *strcpy(char *dst, char *src) {...},那么它们都是错误的——它必须是char *strcpy(char *dst, const char *src) {...}.

  3. 也不要使用标准strlen函数,这意味着您根本不必执行 a #include <string.h>。如果你需要它,也可以编写你自己的版本strlen。(如果您编写自己的strcpy代码是为了作为教学练习,这通常是要求:通常作业会说“您不得使用标准库中的任何其他函数。”)

  4. #include <string.h>不要因为您正在调用而执行 a strlen,而是在文件顶部为其提供您自己的原型:extern size_t strlen(const char *);. (出于多种原因,这通常是一个非常糟糕的主意,除非在极端情况下并且当您确切地知道自己在做什么时,否则这不是一个可以采取的步骤。)

注意您得到的“重新定义”错误是来自编译器还是链接器也可能很重要。如果是编译时错误,例如“ conflicting types for 'strcpy'”,则表示您可能需要注意上面的第 2 点。但是,如果它是像 " ld: duplicate symbol '_strcpy'" 这样的链接时错误,您可能无能为力,您将不得不退回到第 1 点。

于 2018-06-16T10:20:06.310 回答