0

ファイルの内容全体を出力する C コードがいくつかあります。プログラムは以前はファイルを正常に印刷していましたが、1 秒印刷すると、絶対にあってはならない 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奇妙な文字と残りの間に改行を入れて)。

単純にすべてを印刷すると ( a 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;
}
4

3 に答える 3

2

feof() を使用しないでください (少なくとも、あなたが使用する方法ではありません)。

また、errno の使い方が間違っています。errnoには、一部の操作でエラーが返された後にのみ使用可能な値が含まれます (ほとんどの場合、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;
}
于 2012-01-25T18:01:34.380 に答える
1

コードで起こりうる間違いを無視すると、 -と。isprint()を除くすべての文字が印刷可能であると見なされます。0x000x1f0x7f

UTF BOMや7ビットANSI以外の他の文字などは、引き続き印刷できます(ただし、エンコードによって意味が変わる場合があります)。

于 2012-01-25T17:42:53.080 に答える
0

?:の2番目の演算子を空のままにすると、条件付きの結果と等しくなります。印刷不可能な文字の場合、isprintc(c)は0を返すため、3項演算子の条件付き部分は!0であり、これは1に等しくなります。したがって、putcharは無効なASCII文字を印刷しようとして中断します。

于 2012-01-25T17:42:01.473 に答える