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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

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

Q&A

解決済

2回答

3548閲覧

C++でバイナリモードでjpgタグ取得

BeatStar

総合スコア4958

C++

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

0グッド

0クリップ

投稿2016/09/26 01:40

C/C++ ( いわゆる BetterC ) でやっています。
コンパイラは MinGW ( g++ ) です。

jpgタグで、キーワードタグ ってありますよね。
名称は正しくないかもしれませんが、
Windows付属の Explorer で jpgファイルを選択して「プロパティ(R)」を選択すると出てくるダイアログで、

「詳細」→ 「タグ」の部分で編集できるタグです。

これをC/C++のプログラムから読み取り、指定タグを含んでいるかどうかをチェックする関数を作っています。

簡易版なので、いくつか問題があるかもしれませんが。

C++

1#include<iostream> 2#include<fstream> 3#include<string> 4 5using namespace std; 6 7// JpgFilePath を読み込み、Tagを取得する ( string &Tags が戻り値扱い ) 8bool GetJpgTag( const string JpgFilePath, string &Tags ){ 9 10 char c; 11 12 string str; 13 14 // 指定したファイルをバイナリファイルとして読み込む 15 ifstream ifs( JpgFilePath.c_str(), ifstream::binary ); 16 if( !ifs ) return false; 17 18 // チェックするために 適当にmake.txt に指定ファイルの中身をバイナリファイルとして書き込む 19 ofstream of( "make.txt", ifstream::binary ); 20 21 while( ifs.get(c) ){ 22 of << c; // 一応書き込んでみる 23 str += c; // string に記録 24 } 25 26 Tags = str; 27 28 if( Tags.length() == 0 ) return false; 29 30return true; // ここまで来るならエラーに引っかからなかったため true を返す 31} 32 33int main( int argc, char *argv[] ) 34{ 35 string result; 36 37 if( GetJpgTag( "test1.jpg", result ) == false ) cout << "error" << endl; 38 39 string str1; 40 string str2; 41 string str3; 42 string str4; 43 44 str1 = "MakeFile"; 45 str2 = "Main Procedure"; 46 47 str3 = "this"; 48 49 str4 = "答え"; 50 51 if( result.find( str1 ) != string::npos ) cout << str1 << " is found" << endl; 52 else cout << str1 << " is not found" << endl; 53 54 if( result.find( str2 ) != string::npos ) cout << str2 << " is found" << endl; 55 else cout << str2 << " is not found" << endl; 56 57 if( result.find( str3 ) != string::npos ) cout << str3 << " is found" << endl; 58 else cout << str3 << " is not found" << endl; 59 60 if( result.find( str4 ) != string::npos ) cout << str4 << " is found" << endl; 61 else cout << str4 << " is not found" << endl; 62 63return 0; 64}

対象ファイル ( "test1.jpg" ) に

"MakeFile0;Main Procedure;答え;ロジック"

とタグ追加し、

上記プログラム ( もちろん、コンパイル済み ) を実行したところ、


MakeFile is found
Main Procedure is found
this is not found
答え is not found


となりました。

半角英数字の場合は問題ないのですが、日本語等の全角文字の場合、
false になります。

"一応書き込んでみた" make.txt を( テキストファイルとして )見ると、

関係がありそうな部分を抽出して書くと、

<x:xmpmeta xmlns:x="adobe:ns:meta/>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:dc="http://purl.org/dc/elements/1.1/">
dc:subject
<rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
rdf:liMakeFile0</rdf:li>
rdf:liMain Procedure</rdf:li>
rdf:li遲斐∴</rdf:li>
rdf:li繝ュ繧ク繝・け</rdf:li>
</rdf:Bag>
</dc:subject>
</rdf:Description>
<rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:MicrosoftPhoto="http://ns.microsoft.com/photo/1.0/">
MicrosoftPhoto:LastKeywordXMP
<rdf:Bag xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
rdf:liMakeFile0</rdf:li>
rdf:liMain Procedure</rdf:li>
rdf:li遲斐∴</rdf:li>
rdf:li繝ュ繧ク繝・け</rdf:li>
</rdf:Bag>
</MicrosoftPhoto:LastKeywordXMP>
</rdf:Description>
<rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:dc="http://purl.org/dc/elements/1.1/"/>
<rdf:Description rdf:about="uuid:faf5bdd5-ba3d-11da-ad31-d33d75182f1b" xmlns:MicrosoftPhoto="http://ns.microsoft.com/photo/1.0/"/>
</rdf:RDF>
</x:xmpmeta>

となっていて、

答え = "遲斐∴"

ロジック = "繝ュ繧ク繝・け"

という感じで文字化けしています。

if文での対応付け ( "ロジック" => "繝ュ繧ク繝・け" 等 ) すれば確かに可能ですが、
これだとユーザが定義することが難しい ( あるいは 複雑になる ) のでどうすればいいのか。。。

外部ライブラリに頼る方法もありますが、
自分でコンパイルしなければいけないし。

( するのはいいが、Windowsのため、makeがデフォルトで入っていない。。。
インストールしたのはいいが、
"make Makefile" と打っても 「指定したメイクファイルにすることはありません。」となるし、
"make" と打っても 「対象ファイルがありません。」となるし。。。
コンパイルできない!! )

VC++ で DLL にして。。。とやるのはいいが、
C/C++ の場合、(外部ライブラリが)STL対応でなければ
C言語のように 文字列は 要素数を指定しなければならないし。。。

上記ソースコードをかなり変えてもいいので、
jpgファイルをファイル読み込み( バイナリモード ) で読み込み、
日本語対応で 指定タグの存在をチェックする方法を宜しくお願い致します。

※ たぶん丸投げではないと思います。( 一応、自分なりに組んだので。 )

[環境等]
言語 : C/C++ ( いわゆる BetterC )
コンパイラ : MinGW ( g++ )
知りたいこと: 上記ソースコードを 全角のjpgタグ対応にする方法

宜しくお願い致します。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

文字化けは大抵文字コードの不一致です。
手元のファイルで確認したところ、jpegファイル内のタグはUTF-8で記録されているようです。

MinGWもデフォルトはUTF-8ですがソース・コードもUTF-8で記述されている必要が有ります。
UTF-8を使えるエディタでUTF-8へ変換すれば文字化けは解消すると思います。

他に私は使ったことがないのですが文字コードを指定する方法もあります。
-finput-charset=cp932はソース上のリテラルがShift-JISで書かれているとこをコンパイラへ教えるオプションです。たぶん、このオプションを追加しても解消するのではないかと思います。(ついでに-fexec-charset=utf-8はリテラルをutf-8とする指示です。デフォルトなので指定不要な筈。)

デフォルトは両方ともutf-8です。
両方同じなので「変換不要」と解釈されてソースをShift-JISで記述していたら、そのままShift-JISとなり文字化けするのだろうと思います。


make.txtをテキスト・ファイルとして見た時の文字化けですが、UTF-8で記録された文字列をビューワがShift-JISとして表示しているためです。
UTF-8を使えるビューワを使ってUTF-8である旨指定すれば化けないです。

投稿2016/09/26 05:11

編集2016/09/26 05:13
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

if文での対応付け ( "ロジック" => "繝ュ繧ク繝・け" 等 ) すれば

文字コードの不整合問題です。UTF-8エンコーディングで保存された "ロジック" を、Shift-JISとしてデコードすると "繝ュ繧ク繝・け" となります。比較的新しいコンパイラ(C++11対応)ならば、比較対象を u8"ロジック" のように UTF-8文字列リテラル を使って記述できます。

投稿2016/09/26 04:54

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2016/09/26 05:57

ご回答ありがとうございます。 忘れていました。 追加で。 MinGW といっても、最新版でなく、書籍についていたコンパイラです。 最新版も試してみましたが、pthread がないとかのエラーをはきまくりで... pthread もインストールしてやってみるとコンパイルは通りましたが ( SETコマンドで一時的にパスを通したからか?) 実行すると "libstdc++-6.dll" がないため... 等で実行できません。 なので、 古いコンパイラ ( C++11 以前 ) でもコンパイルできるようなもので、 UTF-8文字列リテラル のようなものってないでしょうか? あと、 今回のソースコードはプログラムが指定していますが、 ユーザ入力によって... という風にしたいのですが、 上記の方法でOKなのでしょうか。 WinAPI の TEXTマクロは 変数無理なので、 そのタイプかどうか...
Chironian

2016/09/26 09:31 編集

横から失礼します。 MinGWは本家のMinimalistは一時期開発が止まってました。(最近再開している様子ですが。) ↓は更新が盛んです。こちらは使えると思いますよ。 https://sourceforge.net/projects/mingw-w64/ ここのインストーラでインストールすると楽です。 https://sourceforge.net/projects/mingw-w64/files/latest/download?source=files 後、dll無しエラーは標準ランタイムのdllを見つけることに失敗してます。 mingwのbinフォルダにパスを通すか、標準ランタイムを静的リンクする必要が有ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問