🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

C++

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

Q&A

解決済

1回答

2234閲覧

Visual Studio 2017でsqlite3を用いるとエラーが発生してしまう。

iwanami

総合スコア9

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

C++

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

0グッド

1クリップ

投稿2021/03/21 04:02

編集2021/03/21 12:57

DXライブラリを用いてVS2017でゲームを制作している初心者です。
sqlite3を以下のサイトを参考にしてVS2017に実装しようとしています。
https://bit.ly/3lxG6Mj

ですが必ず決まった所(あ)でエラーが発生してしまいます。
調べてみると、ItemCallback関数のdata[2]の値が整数を表現していない事が分かりました。
data[0],data[1]までは正しい値が入っていたのですが、data[2],data[3],data[4]は0という値にしかなりません。
ItemCallback関数の中でどういう処理がされているのか僕には分からないので、どなたか分かる方がいましたらアドバイス頂けると助かります。

以下のプログラムはメインプログラムの一部です。
全てを載せると何千行となってしまうので一部だけ載せていますが、sqlite3に用いている部分はここしかなく、また他の部分は何度も確認してエラーが起こらなかったので、間違いがあるなら以下のプログラムの中にしかないと思います。

(追記)
すみませんエラーメッセージを載せるのを忘れていました。
正確にはエラーメッセージではなく、例外処理なのですがそれも載せておきます。
「ハンドルされない例外が 0x00E29026 (game.exe) で発生しました: 無効なパラメーターを致命的と見なす関数に無効なパラメーターが渡されました。」

C++

1//「アイテムの仕様」のクラス 2class ITEM_SPEC { 3public: 4 int id = -1;//ID 5 string name = "";//名前 6 int i_type = -1;//アイテムの種類 7 int price = -1;//買値 8 int selling = -1;//売値 9}; 10 11vector<ITEM_SPEC> vitem_s; 12 13//sqlite3に用いる関数 14int CountCallback(void* pOutCount, int size, char **rec, char **ColName) { 15 int *count = (int*)pOutCount; 16 *count = atoi(*rec); 17 return 0; 18} 19 20//sqlite3に用いる関数 21int ItemCallback(void* iteminfo, int size, char **data, char **ColName) { 22 vector<ITEM_SPEC> *vitem = (vector<ITEM_SPEC>*)iteminfo; 23 ITEM_SPEC item; 24 25 item.id = atoi(data[0]); 26 item.name = data[1]; 27 item.i_type = atoi(data[2]);//・・・(あ)ここで例外処理が起こる。 28 item.price = atoi(data[3]); 29 item.selling = atoi(data[4]); 30 31 vitem->push_back(item); 32 33 return 0; 34} 35 36//sqlite3のブロック 37 { //sqlite3を用いでデータベースからデータを取得する 38 char *errMsg = 0; 39 40 sqlite3 *ItemDB = 0; 41 int rc = sqlite3_open("Item.db", &ItemDB); 42 if (rc != SQLITE_OK) { 43 return; 44 } 45 46 char Create_SQL[] = "create table ItemTable (" 47 "ID integer primary key," 48 "名前 text not null unique," 49 "道具の種類 integer not null," 50 "買値 integer not null," 51 "売値 integer not null" 52 ")"; 53 54 sqlite3_exec(ItemDB, Create_SQL, 0, 0, &errMsg); 55 56 char Insert_SQL[] = "insert into ItemTable(ID,名前,道具の種類,買値,売値)" 57 "values(%d,'%s',%d,%d,%d)"; 58 59 FILE *fp; 60 if ((fp = fopen(database_file02.txt, "r")) == NULL) { 61 printfDx("%sが開けません\n", database_file02.txt); 62 sqlite3_close(ItemDB); 63 return; 64 } 65 66 char dummy[1000], name[100], InsertSQL[1000]; 67 int iCount 68 int id = 0;//ID 69 //string name = ""; 70 int i_type = -1;//アイテムの種類 71 int price = -1;//買値 72 int selling = -1;//売値 73 74 fgets(dummy, 1000, fp);//列名無視 75 76 int r = 0; 77 78 79 while (1) { 80 fscanf(fp, "%d%s%d%d%d", &id,name,&i_type,&price,&selling); 81 82 if (feof(fp)) 83 break; 84 85 sprintf(InsertSQL, Insert_SQL, id, name, i_type, price, selling); 86 sqlite3_exec(ItemDB, InsertSQL, 0, 0, &errMsg); 87 } 88 89 char Select1_SQL[] = "select count(*) from ItemTable"; 90 91 sqlite3_exec(ItemDB, Select1_SQL, CountCallback, &iCount, &errMsg); 92 93 char Select2_SQL[] = "select * from ItemTable"; 94 95         //この関数のItemCallbackでエラーが起きている。 96 sqlite3_exec(ItemDB, Select2_SQL, ItemCallback, &vitem_s, &errMsg); 97 98 99 sqlite3_close(ItemDB); 100 }

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

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

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

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

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

javahack

2021/03/21 04:07

エラーが出ているなら、質問文を編集してエラーメッセージを省略せずに載せましょう。
iwanami

2021/03/21 04:14

追記しましたので確認お願いします。
退会済みユーザー

退会済みユーザー

2021/03/21 09:50

ソースコードはレイアウトが崩れたりするので、コードの挿入で記入してください。
iwanami

2021/03/21 10:10

回答ありがとうございます。 追記しましたので確認の方お願いします。
dodox86

2021/03/21 10:11

[2021/03/21 19:06]の質問文の編集「3プログラムをコード化しました。」を読んで: いや、```C++~``` でくくるのはC++のソースコード部分だけで良いのです。説明の全文入れたらそれはそれで読みづらいですよね。プレビューを活用しましょう。(尚、この欄での指摘は回答ではなく、単に「質問への追記・修正、ベストアンサー選択の依頼」です)
iwanami

2021/03/21 10:18

回答ありがとうございます。 修正したので確認お願いします。 という事はこの欄に来るコメントには返信しない方がいいのでしょうか。
退会済みユーザー

退会済みユーザー

2021/03/21 10:21

返信はしたほうがいいですけど、修正しましたくらいでいいと思います。 細かい事言うと、外部リンクもリンクの挿入で入れた方がいいですけど、結局のところ回答してくれる人に対してどれだけ読みやすくするかという話になります。自分が回答する人だったら、読みやすい質問の方が回答しやすいですよね。
dodox86

2021/03/21 10:22

> という事はこの欄に来るコメントには返信しない方がいいのでしょうか。 いえ、必ずしもそうではないです。何かしら問われているのであれば答えた方が良い場合もあるし、質問本文の修正や追記で済むことであればそれで終わりです。時と場合によります。他の方の質問回答を参考にしてみてください。
iwanami

2021/03/21 10:36

なるほど、まだteratailをそんなに触った事が無いので使い方のアドバイス等はとても助かります。 色々と修正しながらやっていこうと思います。
guest

回答1

0

ベストアンサー

sqlite3_execに与えるコールバック関数は:

int callback(void*,int,char**,char**)

にもかかわらず、

int ItemCallback(void* iteminfo, int size, char data, char ColName) { ... }

第3/第4引数の型が異なっています。

投稿2021/03/21 05:41

episteme

総合スコア16612

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

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

iwanami

2021/03/21 06:39

回答ありがとうございます。 teratailでは「**」とすると太文字になり消えてしまう仕様がある事をしりませんでした。 実際のプログラムでは「**」はちゃんとついております。 確認の方宜しくお願いします。
episteme

2021/03/21 07:19 編集

どうやって確認すりゃえぇですか? なぜに僕が確認せにゃならんのですか。 Markdownで書き直してください。
episteme

2021/03/21 07:15

int ItemCallback(void* iteminfo, int size, char * *data, char * *ColName) にとびこんだとき、sizeは正当な値が得られますか?
iwanami

2021/03/21 09:34

まだMarkdownの使い方に慣れてないですがとりあえず修正しておきました、ていう意味で返信したつもりなのですが...そんなに気に障る事を言いましたか。 sizeを見たのですが、2という間違った値が入ってました。 これを見て多分Item.dbの設定が間違っているんじゃないかと思ったのですが、確認作業だけで結構時間がかかるので、一旦返信しておきます。
episteme

2021/03/21 13:05 編集

size = 2 なら有効なのは data[0], data[1] なので data[2] でコケますわな。 できあがった Ite,db に対し同じ SELECT 文を "sqlite3.exe" で食わせてみては?
iwanami

2021/03/21 13:03

確認してみたのですがItem.dbが更新されてない事が原因でした。 ただ参考サイトと比較してもどこを修正したらいいのか分かりません。
dodox86

2021/03/21 13:06 編集

[すれ違い、指摘済みだったので削除]
iwanami

2021/03/21 13:16

size=2というのは、前に試しでやったプログラムのデータです。 それが更新されると思っていたのですが更新されていませんでした。 (途中で更新に気づきましたが一応載せておきます) epistemeさん プログラムを実行して出来上がるItem.dbは白紙で0KBでした。 質問のプログラムには書いてないのですが、実際のプログラムでは最後にselect文で中身を確認しています。なのでselectをしても何も実行されません。
episteme

2021/03/21 21:12

sqlite3_exec の戻り値/error-message を確認してみて。何らかのエラーが報告されるはず。
dodox86

2021/03/22 00:26

>@質問者さん エラー(と言うより致命的例外、異常終了)が起きる "select * from ItemTable";のsqlite3_execの実行までにテーブルのcreate, データのinsert、select count(*)...によるデータ件数の取得をやっています。まず、ここまで適切(意図通りテーブルが作成されて、データが入っていて、件数も合っている)かを確認するべきです。プログラムに不安があるのであれば、確実に動作する外部のツール「DB Browser for SQLite」やSQLiteのクライアント、コマンドラインツールでデータベースファイルの内容を確認してください。
iwanami

2021/03/22 05:27 編集

epistemeさん epistemさんが言っていたように戻り値は1でerrMsgに「unrecognized token "^"」というメッセージがありました。 これについて調べてみたらどうやらsqlite3に用いていた日本語が駄目文字だったようで、全部英語にしたらうまくいきました。 dodox86さん 駄目文字が原因でした。Item.dbは白紙だったのでinsert,selectは全て実行されない状態でした。 >プログラムに不安があるのであれば、確実に動作する外部のツール「DB Browser for SQLite」やSQLiteのクライアント、コマンドラインツールでデータベースファイルの内容を確認してください。 そのようなツールもあるのですね、sqlite3で困ったら参考にします。 皆さん回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問