我有一些C代码应该打印文件的全部内容。程序之前打印的文件很好,但是当它打印一秒钟时,我一直看到一个肯定不应该出现的Unicode字符。
int c = fgetc(file);
putchar((!isprint(c) ? : c));
(包裹在while(!feof(file))
)
应该只打印ASCII可打印字符,除非我弄错了。无论如何,它打印的第一件事是\357\277\275
,它不是ASCII,并且不可打印。
该文件仅包含:foo+bar.foo+t-bar.foo+completely fake
并打印出这个:�foo+bar.foo+t-bar.foo+completely fake
(在奇怪的角色与其余角色之间换行)。
只需打印全部(la putchar(c)
)就可以在行尾添加完全相同的字符。
我甚至尝试使用另一个文件(通过重命名旧文件并使用软链接到另一个文件),但我得到了完全相同的结果。
如果文件为空,它也会这样做。
该文件是完全纯文本,使用vim创建,并且没有任何特殊之处。
这是原始代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
int main(void)
{
char *headp = "../include/header";
char *listp = "../.piclist";
FILE *head, *list;
puts("Content-Type: text/html; charset=utf-8\nExpires: 0\n");
puts("<!DOCTYPE html>\n<html lang='en'>\n<head>");
puts("\t<title>Foo</title>");
puts("\t<link rel='stylesheet' href='/css/main.css' />");
puts("\t<link rel='stylesheet' href='/css/foo.css' />");
puts("</head>\n<body>");
head = fopen(headp, "r");
if (errno) {
perror("cannot open include/header");
errno = 0;
} else {
while (!feof(head)) putchar(fgetc(head));
putchar('\n');
fclose(head);
}
list = fopen(listp, "r");
if (errno) perror("cannot open .piclist");
else {
while (!feof(list)) {
while (!feof(list)) {
int c = fgetc(list);
putchar((!isprint(c) ? : c));
}
}
fclose(list);
} /* else */
fputs("\n<footer>\n\t<hr />\n\t<p>Copyright 2011-2012 the ", stdout);
fputs("<a href='mailto:foo@example.com'> ", stdout);
fputs("Foo Bar of Baz</a> of ", stdout);
fputs("<a href='http://blah.org'>Blah United ", stdout);
fputs("</a></p>\n</footer>\n</body>\n</html>\n",stdout);
return 0;
}
答案 0 :(得分:2)
不要使用feof()(至少不是你使用它的方式)
另外,你对errno的使用是错误的。 errno only 在某些操作指示错误返回后包含可用值(通常为NULL,或-1作为返回值)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
int main(void)
{
char *headp = "../include/header";
char *listp = "../.piclist";
FILE *head, *list;
int ch;
puts("Content-Type: text/html; charset=utf-8\nExpires: 0\n");
puts("<!DOCTYPE html>\n<html lang='en'>\n<head>");
puts("\t<title>Warrenton Latin School | Gallery</title>");
puts("\t<link rel='stylesheet' href='/css/main.css' />");
puts("\t<link rel='stylesheet' href='/css/gallery.css' />");
puts("</head>\n<body>");
head = fopen(headp, "r");
if (!head) {
perror("cannot open include/header");
errno = 0;
} else {
while (1) {
ch = fgetc(head);
if (ch == EOF) break;
putchar(ch);
}
putchar('\n');
fclose(head);
}
list = fopen(listp, "r");
if (!list) perror("cannot open .piclist");
else while (1) {
ch = fgetc(list);
if (ch == EOF) break;
putchar((!isprint(c) ? : c));
}
fclose(list);
fputs("\n<footer>\n\t<hr />\n\t<p>Copyright 2011-2012 the ", stdout);
fputs("<a href='mailto:warrentonlatinschool@gmail.com'> ", stdout);
fputs("Warrenton Latin School</a> co-op of ", stdout);
fputs("<a href='http://warrentonumc.org'>Warrenton United ", stdout);
fputs("Methodist Church</a></p>\n</footer>\n</body>\n</html>\n",stdout);
return 0;
}
答案 1 :(得分:1)
忽略代码中可能出现的错误isprint()
会将所有字符都视为可打印的,0x00
- 0x1f
和0x7f
除外。
UTF BOM和7位ANSI之外的其他字符仍然可以打印(尽管它们的含义可能会因编码而改变)。
答案 2 :(得分:0)
当您离开第二个运算符?:empty时,它等于条件的结果。对于不可打印的字符,isprintc(c)返回0,因此trenary运算符的条件部分是!0,等于1.因此putchar尝试打印无效的ASCII字符并中断。