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

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

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

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

解決済

C++ バイナリ形式のファイルを読み込みvectorに格納する方法

ddp
ddp

総合スコア17

C++

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

2回答

0評価

0クリップ

2571閲覧

投稿2020/10/08 05:59

編集2020/10/08 08:32

以下のコードは16進数の数値羅列が記述されたテキスト形式のファイルを読み込み、8bitごとの数値を16進数でvector aに格納するコードです。

c++

#include <fstream> #include <iostream> #include <sstream> #include <string> #include <vector> class read_rom{ public: int rom_data; void fetch(std::string filename); }; void read_rom::fetch(std::string filename){ std::ifstream ifs(filename); if (!ifs){ std::cout << "Error! File can not be opened" << std::endl; }else{ std::string buf; std::string buf_line; std::vector<int> a; while (std::getline(ifs, buf)){ std::cout << std::hex << std::showbase << buf << std::endl; std::stringstream ss{buf}; while (std::getline(ss, buf_line, ' ')){ int buf_num = std::stoi(buf_line, nullptr, 16); int up = buf_num >> 8 & 0xff; a.push_back(up); int down = buf_num & 0xff; a.push_back(down); } } std::cout << std::hex << std::showbase << a[16] << std::endl; } } int main(){ read_rom rom; std::string filename = "../test"; rom.fetch(filename); } //読み込んでいるファイル("../test") 7f45 4c46 0101 0100 0000 0000 0000 0000 0300 2800 0100 0000 b125 0000 3400 0000 54d2 2800 0004 0005 3400 2000 0a00 2800 2b00 2a00 0100 0070 b47e 0200 b47e 0200 b47e 0200 8008 0000 8008 0000 0400 0000 0400 0000 0600 0000 3400 0000 3400 0000 3400 0000 4001 0000 4001 0000 0500 0000 0400 0000 0300 0000 7401 0000 7401 0000 7401 0000 1900 0000 1900 0000 0400 0000 0100 0000 0100 0000 0000 0000 0000 0000 0000 0000 3887 0200 3887 0200 0500 0000 0000 0100 0100 0000 5090 0200 5090 0300 5090 0300 d00f 0000 e410 0000 0600 0000 0000 0100 0200 0000 209d 0200 209d 0300 209d 0300 2001 0000 2001 0000 0600 0000 0400 0000 0400 0000 9001 0000 9001 0000

上記のようなテキスト形式ではなく、バイナリ形式のファイルを読み込み、8bitごとの数値を16進数で格納する場合にはどのように記述すれば良いでしょうか。

~~コンパイル時にエラーは無いですが、実行すると以下の画像のよ
うな出力結果となります。
コンパイルコマンドg++ -std=c++14 -g -Og -pipe -Wall
~~
※ascii部分?をうまくコピーできないので、画像で張り付けています。

sublime-text コンソール

画像にもありますが、teminateされています。

terminate called after throwing an instance of 'std::invalid_argument'

what(): stoi

お聞きしたい点は2点あります。

  1. terminateされる理由

stoi部分で不正な引数が使用されているとあるようですが、なぜこのようになるのかわかりません。

  1. 出力結果

~~出力がasciiになっている(一部のみ?)理由がわかりません。
~~

環境はWindowsで以下の通りです。

$ g++ -v

Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\g++.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/9.2.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-9.2.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-static --enable-shared --enable-threads --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --enable-libgomp --disable-libvtv --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --disable-build-format-warnings --prefix=/mingw --with-gmp=/mingw --with-mpfr=/mingw --with-mpc=/mingw --with-isl=/mingw --enable-nls --with-pkgversion='MinGW.org GCC Build-20200227-1'
Thread model: win32
gcc version 9.2.0 (MinGW.org GCC Build-20200227-1)~~

どなたかご教授ください。以上、よろしくお願いいたします。

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

mjk

2020/10/08 07:13 編集

私の環境(Win10+WSL2+VSCode+Ubunts20)ではコードそのままコピペでエラーなく動作しました。 https://gyazo.com/572289c9831ecf2a730b67aaead0c08e 以下、何かしらの参考ヒントになれば幸いです。的外れかもしれませんがあしからず。 エラー関連:terminate called after throwing an instance of https://teratail.com/questions/288345 文字化け関連:文字コードがUTF8かSHIFT-JISかの違いでよく起きます https://teratail.com/questions/152379
FKD

2020/10/08 07:20

質問にはバイナリ形式とありますが、プログラムはテキスト形式で読み込んでいます。 実際のtestファイルはどちらの形式なのでしょうか?
FKD

2020/10/08 07:25

※先頭が0x7fELFなので、バイナリファイル(*.oファイル?)かなと推測しているのですが・・・
ddp

2020/10/08 07:28

上記のような16bitの数値が羅列されているファイルです。 ご指摘の通り、バイナリファイル(01の羅列)ではなく、上記のようなテキスト形式です。 有難うございます。タイトルも変更できるようでしたら、変更します。
ddp

2020/10/08 07:29

>>mjkさん コメントありがとうございます。 なるほど、WSL2 Ubunts20では動作するのですね。。。 当方はWSLではないです。
mjk

2020/10/08 07:42 編集

https://paiza.io/projects/4mIzezc18IQAiithQ14pyQ オンラインコンパイラー(正式名称知らないので仮称です)でもエラーは出ませんでした。 (ファイル名の指定だけ少し変更してます。) なので実行環境に原因がありそうかなと推測。
ddp

2020/10/08 07:55

>mjkさん オンラインコンパイラーで検証頂きありがとうございます。 なるほど。。実行環境はWindows、migwになります。 g++ -v の出力を質問文に追記しました。
yohhoy

2020/10/08 08:07 編集

> 上記のような16bitの数値が羅列されているファイルです。 > ご指摘の通り、バイナリファイル(01の羅列)ではなく、上記のようなテキスト形式です。 と仰っていますが、実行結果は「バイナリファイル」を読み込んだと解釈すれば2点とも説明可能です。 テキストファイルとバイナリファイルについて誤解されているようです。
mjk

2020/10/08 08:22 編集

私も素人なので直接の原因を突き止められることは思いつかないのですが、こちらは32bit環境では無く64bit環境です。 あと気になることはVSCodeをお使いなのでしょうか別のIDE? 出力先はコマンドプロンプト? testファイルの保存形式はUTF8になっている? (Win10のアプデ次第ではメモ帳の保全形式はANSI=SHIFT-JISがデフォルトだったはず)
ddp

2020/10/08 08:21

>yohhoyさん ご指摘有難うございます。 再度確かめてみると、バイナリ形式でした。。皆さま誠に申し訳ありません。 sublimetextで見ると、勝手に16bit表記に変換されて表示されるようで、勘違いしていました。 vimで見るとばっちりバイナリ形式でした。 バイナリ形式のデータを、8bitずつvectorに16進数で格納するにはどのように記述すれば良いでしょうか。 タイトルなど、のちほど改めさせて頂きます。
ddp

2020/10/12 04:22

>>mjkさん 情報有難うございます。 vectorについて、回答者の情報と相まって大変勉強になりました。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

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

C++

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