【问题标题】:ERROR :- passing argument 1 of 'get_string' from incompatible pointer type [-Wincompatible-pointer-types]错误:- 从不兼容的指针类型 [-Wincompatible-pointer-types] 传递“get_string”的参数 1
【发布时间】:2021-12-28 20:57:25
【问题描述】:

请大家告诉我的代码有什么问题。 我已经添加了 cs50 库和头文件,但似乎无法正确执行。 我是初学者,想听听您的建议。

代码:-

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

int main(void)
{
    string s = get_string("Input:   ");
    printf("Output: ");
    int n = strlen(s);
    for( int i = 0; i < n; i++)
    {
        printf("%c", s[i]);
    }
    printf("\n");
}

错误:-

3.c: In function 'main':
3.c:7:27: warning: passing argument 1 of 'get_string' from incompatible pointer type [-Wincompatible-pointer-types]
    7 |     string s = get_string("Input:   ");
      |                           ^~~~~~~~~~~
      |                           |
      |                           char *
In file included from 3.c:2:
C:/msys64/mingw64/x86_64-w64-mingw32/include/cs50.c:78:28: note: expected 'char **' but argument is of type 'char *'        
   78 | string get_string(va_list *args, const char *format, ...)
      |                   ~~~~~~~~~^~~~
3.c:7:16: error: too few arguments to function 'get_string'
    7 |     string s = get_string("Input:   ");
      |                ^~~~~~~~~~
In file included from 3.c:2:
C:/msys64/mingw64/x86_64-w64-mingw32/include/cs50.c:78:8: note: declared here
   78 | string get_string(va_list *args, const char *format, ...)

【问题讨论】:

  • 您使用的是 C 还是 C++ 编译器?顺便说一句,如果该库与大多数其他库一样,您应该包括 cs50.h,而不是 cs50.c
  • 我正在运行 C 编译器,当我尝试同时运行两者时,cs50.c 在 VS Code 上工作而不是 cs50.c。跨度>
  • 您不应该(极少)包含.c 文件。您应该像documentation 所说的那样包含头文件。另外,@kaylum 在下面说了什么。 (不幸的是,我今天不能更多地投票给 cmets)
  • @MokshBansal 不不,没问题。只需包含cs50.h 并将-lcs50 添加到编译命令的末尾即可。 gcc -o executable source.c -lcs50。如果cs50 库未安装在标准搜索位置,您也需要提供该位置:gcc -o executable source.c -Lpath_to_libcs50 -lcs50
  • @MokshBansal 好的,如果您关注了该视频,您可能没有图书馆。然后您可以将cs50.c 添加到编译行:gcc -o executable source.c cs50.c

标签: c string char cs50


【解决方案1】:

cs50 文档声明您应该包括cs50.h,而不是cs50.chttps://cs50.readthedocs.io/libraries/cs50/c/#c.get_char https://cs50.readthedocs.io/libraries/cs50/c/#c.get_string

您需要在包含路径中添加头文件。

【讨论】:

    【解决方案2】:

    在 cmets 和之前的答案中已经说明,您不应包含 cs50.c 文件,而应仅包含 cs50.h 文件并将 cs50.c 文件链接到您的项目。

    这通常是正确的,除非您有非常具体的理由采取不同的做法。

    但是...通常这不会导致我们在问题中看到的错误。 这是因为cs50.c 文件本身包含cs50.h,我们应该让所有定义和声明可见。

    在这个特定的案例中,我们遇到了一些 CS50 库的特定实现细节,这有点令人惊讶。而且也没有必要......

    让我们仔细看看标题:

    // cs50.h
    string get_string(va_list *args, const char *format, ...) __attribute__((format(printf, 2, 3)));
    #define get_string(...) get_string(NULL, __VA_ARGS__)
    

    在这两行之后,我们可以按照这个问题的作者的意图使用get_stringstring s = get_string("Input: ");

    为什么有人会认为将函数隐藏在同名但参数不同的宏后面是个好主意,这并不明显。 在大多数其他 API 中,该函数的名称与宏的名称不同。 但是,没关系...

    现在让我们看一下C文件:

    // cs50.c
    #include "cs50.h"
    ...
    #undef get_string
    string get_string(va_list *args, const char *format, ...)
    {
    ...
    }
    

    如果你自己编译这个文件,一切都很好。 .c 文件不需要宏,可以在定义函数之前去掉它。

    但是,如果您将其包含在您自己的文件中,而您应该在其中使用宏,则不再可能。 如果您直接包含文件,undef 会破坏 API。

    这强调了您应该只包含标题的事实。它们应该被包括在内,并且是相应地制作的。保存实现的.c 文件不一定是这样制作的,正如我们所见......

    附带说明:这个#undef 根本没有必要。你可以简单地这样做:

    // cs50.c
    #include "cs50.h"
    ...
    string (get_string)(va_list *args, const char *format, ...)
    {
    ...
    }
    

    包含() 标识符get_string 不再匹配宏get_string() 并且不进行替换。 这甚至允许直接包含.c 文件。

    也许他们故意选择这种方式是为了防止包含 c 文件,但我不会打赌。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-24
      • 2021-07-25
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      相关资源
      最近更新 更多