【补档】Dev-C++ 如何导入 bits/extc++.h 头文件?

· · Tech. & Eng.

前言

自从我写完那一篇介绍冷门数据结构的文章后,大家都对文章做出了评论。但也有很多人问我:

主播主播,你的 C++ 扩展头文件确实很强,但还是太吃大脑内存了,有没有什么简单又强势的头文件推荐一下?

有的兄弟,有的。这样简单又强势的头文件就是今天的主角:bits/extc++.h

是不是和我们常用的“万能头文件”很像?没错,我们常用的“万能头文件”导入了 C++ 中所有的基础头文件;而刚才提到的扩展头文件则是导入了 C++ 中所有的扩展功能。

今天,我就教大家如何使用这个头文件。

正文

什么?使用头文件?这不是连一年级小学生都会吗?直接 #include<bits/extc++.h> 不就行了?CEXE 的文章真是越来越水了。

你说得对,但是如果我们把这行代码放到 Dev-C++ 中,它会 CE!报错信息大概是这样的:[Error] iconv.h: No such file or directory

我将会给大家多种方法解决这个问题。

第一种方法 手动添加文件

什么?它说找不到 iconv.h 这个文件?那我们直接手搓这个文件!

先给出这个文件的源代码(相比于原版有删减):

#ifndef _LIBICONV_H
#define _LIBICONV_H
#define _LIBICONV_VERSION 0x0110
extern __declspec (dllimport) int _libiconv_version; 
#undef iconv_t
#define iconv_t libiconv_t
typedef void* iconv_t;
#include <stddef.h>
#include <errno.h>
#ifndef EILSEQ
#define EILSEQ 
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif
    extern iconv_t iconv_open (const char* tocode, const char* fromcode);
#ifndef LIBICONV_PLUG
#define iconv libiconv
#endif
    extern size_t iconv (iconv_t cd,  char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
#ifndef LIBICONV_PLUG
#define iconv_close libiconv_close
#endif
    extern int iconv_close (iconv_t cd);
#ifdef __cplusplus
}
#endif
#ifndef LIBICONV_PLUG
#if 1
#if 0
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#endif
#include <wchar.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
    typedef struct {
        void* dummy1[28];
#if 1
        mbstate_t dummy2;
#endif
    } iconv_allocation_t;
#define iconv_open_into libiconv_open_into
    extern int iconv_open_into (const char* tocode, const char* fromcode,
        iconv_allocation_t* resultp);
#define iconvctl libiconvctl
    extern int iconvctl (iconv_t cd, int request, void* argument);
    typedef void (*iconv_unicode_char_hook) (unsigned int uc, void* data);
    typedef void (*iconv_wide_char_hook) (wchar_t wc, void* data);
    struct iconv_hooks {
        iconv_unicode_char_hook uc_hook;
        iconv_wide_char_hook wc_hook;
        void* data;
    };
    typedef void (*iconv_unicode_mb_to_uc_fallback)
    (const char* inbuf, size_t inbufsize,
        void (*write_replacement) (const unsigned int *buf, size_t buflen,
            void* callback_arg),
        void* callback_arg,
        void* data);
    typedef void (*iconv_unicode_uc_to_mb_fallback)
    (unsigned int code,
        void (*write_replacement) (const char *buf, size_t buflen,
            void* callback_arg),
        void* callback_arg,
        void* data);
#if 1
    typedef void (*iconv_wchar_mb_to_wc_fallback)
    (const char* inbuf, size_t inbufsize,
        void (*write_replacement) (const wchar_t *buf, size_t buflen,
            void* callback_arg),
        void* callback_arg,
        void* data);
    typedef void (*iconv_wchar_wc_to_mb_fallback)
    (wchar_t code,
        void (*write_replacement) (const char *buf, size_t buflen,
            void* callback_arg),
        void* callback_arg,
        void* data);
#else
    typedef void (*iconv_wchar_mb_to_wc_fallback) ();
    typedef void (*iconv_wchar_wc_to_mb_fallback) ();
#endif
    struct iconv_fallbacks {
        iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback;
        iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback;
        iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback;
        iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback;
        void* data;
    };
#define ICONV_TRIVIALP            0 
#define ICONV_GET_TRANSLITERATE   1 
#define ICONV_SET_TRANSLITERATE   2 
#define ICONV_GET_DISCARD_ILSEQ   3 
#define ICONV_SET_DISCARD_ILSEQ   4  
#define ICONV_SET_HOOKS           5  
#define ICONV_SET_FALLBACKS       6 
#define iconvlist libiconvlist
    extern void iconvlist (int (*do_one) (unsigned int namescount,
        const char * const * names,
        void* data),
        void* data);
    extern const char * iconv_canonicalize (const char * name);
    extern void libiconv_set_relocation_prefix (const char *orig_prefix,
        const char *curr_prefix);
#ifdef __cplusplus
}
#endif
#endif
#endif

在 IDE 中输入这一串代码,命名为 iconv.h,接着保存。存到哪里呢?打开桌面上 Dev-C++ 的快捷方式所在的文件夹,依次进入 MinGW64libgccx86_64-w64-mingw324.9.2includec++,把文件保存到当前文件夹即可。

可能会有人不想复制上面的代码,那我就直接给出源文件下载链接了。

接着,重启 IDE 并再次导入 bits/extc++.h,现在应该可以导入了。

当然,在调试的过程中可能会出各种玄学错误。作者建议:遇到玄学错误就立即重装 Dev-C++,否则越改问题越多。顺便给出下载链接。

第二种方法 手动替换

上面的方法在大家平常练习时乐呵乐呵就行了,正式考试肯定不让下载源文件。(当然如果你打 ICPC 系列比赛当我没说……)

但也别慌,先随便导入一个 iostream,按下 Ctrl 键并点击代码中的 iostream,会发现弹出了 iostream 的源文件;不必管它,按下 Ctrl+B 打开它的地址,依次进入 x86_64-w64-mingw32bits,这个文件夹中的 extc++.h 文件就是我们想要导入的那个头文件。

顺便说一句,如果你直接搜 extc++.h 可能会搜到两三个,所以不要直接搜索。

我们打开并查看它的源码。翻到最下面,把下面这一串代码注释掉,保存即可。

#ifdef _GLIBCXX_HAVE_ICONV
 #include <ext/codecvt_specializations.h>
 #include <ext/enc_filebuf.h>
#endif

注释掉以后,其他都不用改变,再次导入就能成功。

第三种方法 使用小熊猫 C++

如果你看到了这一章,请大喊三声:

CEXE 好闪,拜谢 CEXE! 小熊猫 C++ 牛逼!!!

小熊猫 C++ 的编译器比较新,所以可以使用这个头文件。

什么?你还不会配置小熊猫 C++?去看我的往期文章吧!

如果我想从 Dev-C++ 配置最新的编译器,怎么办?也可以去看我的往期文章。这里搬运一下。

我们除了使用小熊猫 C++,还可以在 MinGW 的官网上把 G++ 升级到最新版,即可使用这个头文件。

当然,有时候官网比较慢,这里直接给出 Github 上的下载直链。

下载解压完之后,我们需要配置环境变量。打开控制面板,搜索“编辑系统环境变量”,打开,在弹出的窗口中点击“环境变量”,双击打开“系统变量”中的 Path,新建一个变量。接着先别动,回到解压后的 MinGW64 文件夹,打开其中名为 bin 的子文件夹,并复制其地址。回到环境变量配置窗口,在新的变量中粘贴上刚才复制的地址。接着点击“确定”,一步一步退出即可。

接着,按下快捷键 Win+R,输入 cmd,在命令行中输入 gcc -v。如果输出了一大串东西,而且最后一行是 gcc 的版本(我给出的下载链接版本为 15.1.0),那就说明配置成功了。

考试中的用处

说了这么多,还是为了在考场上能使用这个头文件中的众多黑科技。比如 pb_ds 库,20 行秒杀平衡树板子。

在几年前,CCF 官方发表文章,说可以使用 bits/extc++.h。而且 CCF 还说过不会卡常,刚好弥补了它们常数大的缺点。

这篇文章的正文部分就到此为止了。感谢您的观看!/bx

参考资料

结尾

似乎结尾没什么好说的,那就无聊地统计一下吧。

全文共 6078 字符,阅读大约需要五分钟。

就到这里吧,感谢你的观看。

2025.05.19 By CEXE

幸甚至哉,歌以咏志。