错误:-从不兼容的指针类型[-Wincompatible-pointer-types]传递“get_string”的参数1

q0qdq0h2  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(276)

请告诉我代码有什么问题。我已经添加了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, ...)
a6b3iqyw

a6b3iqyw1#

在注解和前面的答案中已经指出,您不应该包含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文件,但我不会打赌。

nom7f22z

nom7f22z2#

cs50文档指出你应该包含cs50.h,而不是cs50.c。https://cs50.readthedocs.io/libraries/cs50/c/#c.get_charhttps://cs50.readthedocs.io/libraries/cs50/c/#c.get_string
您需要在包含路径中添加头文件。

相关问题