- /* 在 Windows 下有许多编码是GB18030、 后缀是 cue 的文本文件,将其移到 Linux 下使用 shell 命令:
- find . -type f -name "*.cue" -exec iconv -f gb18030 -t utf8 -o {} {} \\;
- 目的是找到当前目录下所有cue文件并转码,然后替换原文件。当 iconv 转码失败时,仍然会将垃圾数据写入原文件。
- 而新的 safe_iconv 在转码失败时不修改原代码。safe_iconv 只适合用于小于 BUFSIZE 的文件:
- find . -type f -name "*.cue" -exec safe_iconv -f gb18030 -t utf8 -o {} {} \\;
- */
- #include <getopt.h>
- #include <iconv.h>
- #include <stdlib.h>
- #include <stdio.h>
- enum {BUFSIZE = 4096};
- static iconv_t cd;
- static char* fromcode;
- static char* tocode;
- static char* infilename;
- static char* outfilename;
- static char inbuf[BUFSIZE];
- static char outbuf[BUFSIZE];
- static FILE* fin;
- static FILE* fout;
- int cmdline_parsed(int argc, char*const* argv)
- {
- int opt;
- opterr = 0;
- while ( (opt=getopt(argc, argv, "f:t:o:l")) != -1 )
- {
- switch (opt) {
- case 'f': fromcode = optarg; break;
- case 't': tocode = optarg; break;
- case 'o': outfilename = optarg; break;
- case 'l': system("iconv -l"); return 0; //当然必须安装有 iconv。
- case '?': fprintf(stderr, "error: option is \\'?\\'\\n"); return 0;
- }
- }
- if (! (fromcode && tocode)) {
- fprintf(stderr, "error: \\'fromcode\\' or \\'tocode\\' is null.\\n");
- return 0;
- }
- infilename = argv[optind];
- return 1;
- }
- size_t file_size(FILE* fin)
- {
- size_t r;
- fseek(fin, 0, SEEK_END);
- r = ftell(fin);
- fseek(fin, 0, SEEK_SET);
- return r;
- }
- int main(int argc, const char** argv)
- {
- char* pinbuf = inbuf;
- char* poutbuf = outbuf;
- size_t inbytesleft;
- size_t outbytesleft;
- size_t count;
- if (! cmdline_parsed(argc, (char*const*)argv)) {
- return EXIT_FAILURE;
- }
- cd = iconv_open(tocode, fromcode);
- if (cd == (iconv_t)-1) {
- fprintf(stderr, "error: f=\\'%s\\' t=\\'%s\\' i=\\'%s\\' o=\\'%s\\'\\n",
- fromcode, tocode, infilename, outfilename);
- return EXIT_FAILURE;
- }
- fin = fopen(infilename, "r");
- if (! fin) {
- fprintf(stderr, "error: \\'fopen(%s, \\"r\\")\\'\\n", infilename);
- return EXIT_FAILURE;
- }
- inbytesleft = file_size(fin);
- if (inbytesleft > BUFSIZE) {
- fprintf(stderr, "error: \\'%d > BUFSIZE\\'\\n", inbytesleft);
- return EXIT_FAILURE;
- }
- fread(inbuf, 1, inbytesleft, fin);
- outbytesleft = BUFSIZE;
- count = iconv(cd, &pinbuf, &inbytesleft, &poutbuf, &outbytesleft);
- if (count == (size_t)-1) {
- fprintf(stderr, "error: \\'iconv()\\'\\n");
- return EXIT_FAILURE;
- }
- if (outfilename == NULL) {
- //printf("%d %d\\n", inbytesleft, outbytesleft);
- printf("%s", outbuf);
- }
- else {
- fout = fopen(outfilename, "w");
- if (! fout) {
- fclose(fin);
- fprintf(stderr, "error: \\'fopen(%s, \\"w\\")\\'\\n", outfilename);
- return EXIT_FAILURE;
- }
- fwrite(outbuf, 1, BUFSIZE - outbytesleft, fout);
- fclose(fout);
- }
- fclose(fin);
- return EXIT_SUCCESS;
- }
- //该片段来自于http://www.codesnippet.cn/detail/2506201512931.html
来源: http://www.codesnippet.cn/detail/2506201512931.html