大家请告诉我的代码有什么问题。 我已经添加了 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, ...)
评论和之前的答案中已经指出,您不应包含
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_string
:string 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 文件,但我不会打赌。
cs50 文档指出您应该包括
cs50.h
,而不是 cs50.c
。
https://cs50.readthedocs.io/libraries/cs50/c/#c.get_char
https://cs50.readthedocs.io/libraries/cs50/c/#c.get_string
您需要在包含路径中添加头文件。
我正在开发 Codeblocs,您需要包含
get_string 需要两个参数。在
""
:之前放置第一个空参数
"Input: "
string s = get_string("", "Input: ");