使用标准C++调用C标准库函数的方法

3

我有几个关于在C++中调用C标准库函数的问题:

  1. 如果我想调用在<stdio.h>中声明的getline()函数,只包含<cstdio>头文件是否就足够了?这在我使用的编译器上可以工作,并且我看到它在<cstdio>中包含了<stdio.h>,但我想知道标准是否保证这一点。
  2. 所有C标准库函数都保证在C++中可用吗?以上面的getline()为例,我注意到在cppreference中的<cstdio>下并没有列出getline()
  3. 对于在std::命名空间中提供的C标准库函数和类型,例如FILEmalloc(),是否通过全局命名空间访问它们存在任何问题,还是更符合习惯地将它们访问为std::FILEstd::malloc()

2
getline不是C标准库函数,而是POSIX函数。如果它在您的编译器的C库中可用,则在C++中也可用。 - molbdnilo
1
假设你在考虑的是POSIX getline函数,并不保证<cstdio>会声明它。尽管可能会声明,但不能保证,因为它既不是标准C++的一部分,也不是标准C的一部分。 - Some programmer dude
你们说得对,我忽略了它是一个POSIX函数,这回答了我上面的前两个问题。 - Mike Sweeney
3个回答

4

您应该始终包含文档中告诉您的内容。(C++标准库实现通常会编写函数以便通过其他包含文件访问,但是依赖于此意味着您的代码不可移植。)请注意,在C语言中没有标准的getline函数。但在C ++中有一个:

std::getline()

在头文件<string>中定义。C++标准通常不能保证C函数在全局范围内可用,甚至不是C++标准库的一部分。这两种语言多年前就开始分歧,因此认为C++在某种程度上是C的超集(包括库)的想法是错误的。

参考:https://en.cppreference.com/w/cpp/string/basic_string/getline


事实证明,正如@molbdnilo指出的那样,我指的是POSIX getline()。关于你最后一个观点,我已经阅读了这个之前的回答,它似乎表明C++标准确保如果你像stdio.h一样包含C头文件,则C函数将在全局范围内可用。 - Mike Sweeney

2

关于#3

.h库必须将其所有名称放置在全局命名空间中,并且还可以将它们放置在std::命名空间中。

c版本的起始位置必须将其所有名称放置在std::命名空间中,并且还可以将它们放置在全局命名空间中。


这是我在之前链接的答案中读到的,但@bathsheba似乎说相反的话:C++标准通常不保证C函数在全局范围内可用。 - Mike Sweeney

0

一般来说,将任何C库与C++链接应该很容易,不仅限于标准头文件。

请注意,您可能需要查阅man手册以确定方法是在哪个unix版本中引入的或者它是否是一个特定的扩展,并自行决定历史起点是否可接受。但如果您编写的是C程序而不是C ++,这也同样适用。

C ++别名头文件包括大多数但不是全部C头文件的功能,但有时您可能会发现获取函数的唯一方法是直接包含C头文件。另一方面,您需要问自己为什么他们选择不包括该方法,通常是因为它已被弃用、危险或非标准。

因此,它的工作方式是使用extern "C"关键字引入C函数,包括C库函数。

当您#include C头文件时,它们通常会包含一些代码,例如:

/* C++ needs to know that types and declarations are C, not C++.  */
#ifdef  __cplusplus
# define __BEGIN_DECLS  extern "C" {
# define __END_DECLS    }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif

__BEGIN_DECLS

...介绍了一组C接口函数的部分。

如果您需要包含一个非常古老的C库,而该库没有这样做,那么您可以轻松地在#include周围添加extern "C"

extern "C" {
#include "ancientinterface.h"
};

你也可以编写符合“C”接口的自己的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接