使编译器允许<a.h>而不是“a.h”

时间:2017-03-23 21:17:18

标签: c++ c include

我有一个第三方库,我希望将其包含在我的代码中,但开发人员通过&lt;&gt;包含了所有本地头文件。编译时导致“没有此类文件或目录”错误的语法。

如果我手动将#include <a.h>更改为#include "a.h",则该文件编译得很好。唯一的问题是,有数百个文件通过&lt;&gt;包含所有类型的标题。

是否有UNIX编译器指令来处理&lt;&gt;哪个找不到“”?

解决方案:

在尝试了几件事之后,我最终使用sed将所有#include <XXX.h>替换为#include "XXX.h"。以下是为整个目录更改它的命令:

find ./ -type f -exec sed -i -E "s/include <(.+).h>/include \"\1.h\"/g" {} \;

这适用于我的具体案例。我不建议用“”替换所有标题包含。

2 个答案:

答案 0 :(得分:1)

在C \ C ++程序中包含头文件(或库)。有两种方法可以做到这一点:

1)。用引号(例如#include "a.h")写文件名  2)。在尖括号中写入文件名(例如#include<a.h>

但两者彼此不同,第一种方法#include"a.h"首先搜索程序当前目录中的文件,然后在C ++库中搜索。而另一方面,如果文件存在,#include<a.h>只查看默认的C ++库,其他明智的编译器会给出错误。

我认为在您的情况下,"a.h"文件位于您计划的当前目录中,这是#include"a.h"工作原因且<a.h>无效的原因。如果你想这样,只需复制文件并将其粘贴到编译器的其他内置头文件所在的目录中。  您只需在资源管理器中搜索"stdio.h",然后打开包含文件的文件夹并粘贴&#34; a.h&#34;在那个文件夹中。然后尝试使用#include<a.h>它会正常工作。 我希望能回答这个问题。

答案 1 :(得分:0)

正式地,C11标准(ISO / IEC 9899:2011)说:

  

6.10.2源文件包含

     

...

     

2

形式的预处理指令      

# include < h-char-sequence > new-line

     

在一系列实现定义的位置搜索由<>分隔符之间的指定序列唯一标识的标头,并导致替换它   指令由标题的全部内容组成。如何指定地点或标题   确定是实施定义的。

     

3表格

的预处理指令      

# include " q-char-sequence " new-line

     

导致由指定的源文件的全部内容替换该指令   按"分隔符之间的指定顺序排列。搜索指定的源文件   以实现定义的方式。如果不支持此搜索,或者搜索   失败后,指令被重新处理,就像它读取

一样      

# include < h-char-sequence > new-line

     

使用相同的包含序列(包括>个字符,如果有的话)来自原始指令。

因此,<header.h>表示法会使预处理程序以实现定义的方式搜索标头。 "header.h"表示法使预处理器以可能不同的实现定义方式搜索标头,如果该搜索失败,则使用与<header.h>相同的搜索进行搜索。 / p>

因此,引用的符号从不会在比角括号表示法更少的位置 - 但角括号符号可能看起来比引用的符号更少。

对于许多编译器(预处理器),-I选项指定要搜索头的额外位置(目录)。通常在默认位置之前搜索这些位置。此外,预处理程序通常会在当前目录或包含源文件的目录或嵌套#include操作的当前头文件中查找标头,或者两者都查找。由于向后兼容的原因,规则通常有点复杂。

例如,c99编译器的POSIX规范说:

  

-I directory

     

更改搜索名称不是绝对路径名的标头的算法,以便在查看常用位置之前查看目录路径名所指定的目录。因此,名称以双引号("")括起来的标题应首先在#include行的文件目录中搜索,然后在-I选项中命名的目录中搜索,并且在通常的地方持续。对于名称用尖括号(<>)括起来的标题,只能在-I选项中指定的目录中搜索标题,然后在通常的位置搜索标题。在-I选项中命名的目录应按指定的顺序进行搜索。如果-I选项用于指定默认搜索的常用位置之一的目录,则结果未指定。实现应在单个c99命令调用中支持至少十个此选项的实例。

Microsoft将拥有自己的这些规则版本。

要解决问题中的问题,您需要将表示法从#include <a.h>更改为#include "a.h",或者您需要将标题安装在无论如何都会找到它的目录中(例如{许多类Unix系统上的{1}}。如果这些都不可接受,则需要在编译器命令行中指定存储/usr/local/include的目录 - 例如,在基于Unix的系统上使用a.h

可能有一种方法可以将编译器配置为查看额外的目录而无需命令行选项。但是,这些技术非常依赖于编译器。您应该更改使用的表示法(尖括号到引号)或将选项添加到编译器命令行。