質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • C++

    4418questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • バイナリ

    32questions

  • ASCII

    15questions

ファイルを開いて、ファイルのエンコード方式がバイナリかASCIIかを調べる

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 888

ryohasegawa

score 112

ファイルを開いて、エンコード方式がバイナリかASCIIか判別できるコードをこのサイトを参考に書いてみたんですが、うまく動作しません(詳しくは下に書いてあります)。
この辺をこうしたらいいなどのアドバイスをもらえませんか?

ifstream ifs(ファイルパス);    //    ファイルを開く

        //    ファイルのオープンに成功しているか
        if (!ifs) {    
            cout << "ファルがひらけれませんでした。\n";
            cout << "何か入力してください。\n";
            cin >> err;
            if (err != "") {
                return 1;
            }    
        }else{
            cout << "ファイルを開きました。\n";
        }

        //    開いたファイルのデータが空だったら
        if (ifs.get() == EOF) {
            cout << "ファイルが空です。\n";
            cout << "何か入力してください。\n";
            cin >> err;
            if (err != "") {
                return 1;
            }
        }

        while ((ifs.get()) != EOF){
            int c = ifs.get();
            cout << c << "/C/\n";

            if (EOF == c){
                cout << "ASCII";        //    ASCII?
                break;
            }else if (c <= 8){
                cout << "バイナリ\n";        //    バイナリ?
                break;
                //ifs.close();
                //return 1;
            }
        }
ファイル名 表示
test_a.txt 表示なし
test_b.txt ASCII
file.pbm バイナリ
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

気になったのは2点

1、ファイルの中身→拝見しました、失礼しました
2、ループ条件を書いた後、そのループ内でifs.getを呼び出していること。

追記:2がバグの原因です。見た感じ、偶数バイトのファイルでバグりそう(1ループごとに2字読んでいて、EOFはループ条件のとこで発生し、種類表示部にたどりつけない)ですが、省略している部分で、ファイルが空か調べるために1文字読み込んでいるため、奇数バイトのときバグっているのだと思います。

ifstream ifs(path);
if(!ifs){
    cout << "fail to open";
}
int c;
while((c = ifs.get()) >= 0x9);
if( c != EOF ){
    cout << "binary" << endl;
}
else{
    cout << "ASCII" << endl;
}


サンプル加筆しました。分からないところは随時補足します。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/06 00:28

    ファイルなんですが、URLで飛べませんか?

    キャンセル

  • 2017/07/06 00:30

    スマホから無事に読めました、思った通り奇数バイトですね(バグが発覚した原因)

    キャンセル

  • 2017/07/06 00:32 編集

    テキスト(全角と半角)と画像ファイルの3パターンで試してみました。
    ASCIIかバイナリかを判別させたい、と考えた時にこのパターンしか思いつきませんでした・・・

    キャンセル

  • 2017/07/06 22:07

    空か調べるために1文字読み込んでいるためずれが発生しているという事ですか?

    キャンセル

  • 2017/07/06 22:32

    はい、「バグが起きる条件が」ずれてます。もちろん、バグを直せばいいだけの話ですが。

    キャンセル

  • 2017/07/06 22:56

    ってことは、どのような処理をしているかを記述したほうがいいですね。
    省略している所を書き足します。
    それと、回答のコードなんですが、コードを書く書き方があるので、それで書いてもらえませか?

    キャンセル

  • 2017/07/06 23:33

    省略補完:ありがとうございます、思った通りでした。
    書き方:?? (スタイルのこと? それとも仕様? 自由に書き換えてくれて大丈夫ですよ。)

    キャンセル

  • 2017/07/06 23:36

    Markdown記法の```でかこってねって事だと思いますよ。単一行のコードに使うやつになっていますので。

    キャンセル

  • 2017/07/06 23:40

    ああああ、最後の閉じ括弧の後の改行が消えてた…修正しましたorz

    キャンセル

  • 2017/07/07 22:49

    lunateaさん説明ありがとうございます。
    majiponiさん変更ありがとうございます。

    キャンセル

  • 2017/07/16 16:26

    テスト期間を挟んでしまい返信が遅くなりました。
    majiponi さん。
    while((c = ifs.get()) >= 0x9);で条件をc = ifs.get()) >= 0x9としていると思うんですが、この条件の説明をいただけますか?
    ifs.get()で一文字読み込んで、それをcに代入しているのは分かるんですが、c >= 0x9がわかりません。

    キャンセル

  • 2017/07/16 17:30

    ループ条件はマニアックに書いてあります。本来は
    (c = ifs.get()) != EOF && c >= 0x9
    とすべきですが、今回は、9との大小比較だけでokです。EOFはマイナスの値と規定されているので、cが9以上の値であれば、EOFでないことは保証されます。そのためEOFか一部の制御文字が出てくるまで読み飛ばして、最後のif文で、EOFが原因でループを抜けたか制御文字が原因か判断しています。

    キャンセル

  • 2017/07/18 23:58

    yumetodo さんにも返信をしたのですが、0x9で分けるのはなぜですか?
    if文の判別は理解しています。ファイルの最後まで到達してループを抜けたのかどうかを判別しているんですよね?

    キャンセル

  • 2017/07/19 00:49

    「あなたの引用した」資料に、0x8以下がバイナリである、と定義されていたからです。別にc > 0x8と書いても同じです。私が0x9で書いた理由は、ループ条件を「テキストコードが続く限り」と肯定形の文章で考え、テキストコードの最小値0x9との比較のほうがより自然である、そう考えたからです。

    キャンセル

  • 2017/07/19 09:50

    なるほど、ありがとうございます。

    キャンセル

+1

拡張子とファイルのフォーマット - yumetodoの旅とプログラミングとかの記録

を見ていただきたいのですが、まず何をテキストファイルと定義するかという問題があります。

テキストファイルとはある文字コード(というと微妙に違うけど)に基づいたbinaryファイルを指します。つまりどの文字コードを想定するかで定義が変わります。0x9で分けるのが妥当かどうか、検討が必要でしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/07 22:49

    ありがとうございます。
    見てきます!

    キャンセル

  • 2017/07/18 23:55

    他サイトも見てきたのですが、なぜ、0x9で分けるのですか?

    キャンセル

  • 2017/07/19 01:06

    私は0x9で分ける根拠は知らないです・・・、Unicode的には不自然・・・

    キャンセル

  • 2017/07/19 09:49

    わかりました。ありがとうございます。

    キャンセル

同じタグがついた質問を見る

  • C++

    4418questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • バイナリ

    32questions

  • ASCII

    15questions