macのbigsurにおいて、C言語からsqliteを操作しています。
以下がサンプルのソースになります。
・sample.c // sample.c // written by mnagaku @ 2006/04/27 // id, worker, change_line_count, commit_date // の形式のデータをDBに取り込み、 // change_line_countの総計の多いworkerのtop10と // commit数(データ数)の総計の多いworkerのtop10を調べます #include <stdlib.h> #include <stdio.h> #include <string.h> #include "sqlite3.h" #define MAX_STR 256 #define MAX_COLUMN 5 // SQL文 #define CREATE_TABLE "CREATE TABLE IF NOT EXISTS bookdata (id INTEGER PRIMARY KEY, \ bookmei TEXT NOT NULL, category TEXT NOT NULL, nesesary TEXT NOT NULL, \ commit_date TEXT NOT NULL)" #define INSERT_TABLE "INSERT OR IGNORE INTO bookdata (id, bookmei, category, \ nesesary,commit_date) values (%s, '%s', '%s', '%s', '%s')" #define SELECT_TABLE "SELECT id, bookmei, category, \ nesesary,commit_date from bookdata" // DBの検索結果を大域変数で保持 typedef struct { char values[MAX_COLUMN][MAX_STR]; } RAW; RAW *sqlResult; int rawSize, columnSize; // 検索結果を1行取得する度に呼ばれるコールバック関数 // 検索結果を1行取得する度に呼ばれるコールバック関数 static int callback(void *option, int columnCount, char **columnValues, char **columnNames) { int columnCounter; if(sqlResult == NULL) { sqlResult = (RAW *)malloc(MAX_COLUMN * MAX_STR * 2); columnSize = columnCount; } else if((sqlResult = (RAW *)realloc(sqlResult, MAX_COLUMN * MAX_STR * (rawSize + 2))) == NULL) return -1; for(columnCounter = 0; columnCounter < MAX_COLUMN && columnCounter < columnCount; columnCounter++) { if(rawSize == 1) strncpy(sqlResult[0].values[columnCounter], columnNames[columnCounter], MAX_STR); strncpy(sqlResult[rawSize + 1].values[columnCounter], columnValues[columnCounter], MAX_STR); } rawSize++; return 0; } // SQLの実行 void sqlExec(sqlite3 *db, const char *sql, sqlite3_callback cb) { char *pStr; free(sqlResult); sqlResult = NULL; rawSize = 0; if(sqlite3_exec(db, sql, cb, NULL, &pStr) != SQLITE_OK) { fprintf(stderr, "Error %s %d: %s\n%s\n", __FILE__, __LINE__, pStr, sql); sqlite3_close(db); exit(0); } } // メイン void main() { char str[MAX_STR], data[5][20], *pStr; int lineCount, dataCount; FILE *fp; sqlite3 *db; // メモリ上にDBを構築 if(sqlite3_open("shoseki.db", &db)) { fprintf(stderr, "Error %s %d: Can't open database %s\n", __FILE__, __LINE__, sqlite3_errmsg(db)); sqlite3_close(db); return; } // テーブル作成 sqlExec(db, CREATE_TABLE, NULL); // データファイル読込み if((fp = fopen("sample.csv", "rt")) == NULL) { fprintf(stderr, "Error %s %d: Can't open datafile.\n", __FILE__, __LINE__); sqlite3_close(db); return; } memset(str, '\0', sizeof(str)); fgets(str, MAX_STR, fp); //ヘッダーの読み飛ばし for(lineCount = 0; fgets(str, MAX_STR, fp) != NULL; lineCount++) { for(pStr = strtok(str, ","), dataCount = 0; dataCount < 4 && strlen(pStr) > 0 && pStr[0] != '\n'; pStr = strtok(NULL, ","), dataCount++) strncpy(data[dataCount], pStr, 20); if(dataCount < 4) { printf("Warnning %s %d: Find illegal data at %d\n", __FILE__, __LINE__, lineCount); break; } // 読み込んだデータをDBに投入 sprintf(str, INSERT_TABLE, data[0], data[1], data[2], data[3],data[4]); sqlExec(db, str, NULL); memset(str, '\0', sizeof(str)); } fclose(fp); // DBの検索 sqlExec(db, SELECT_TABLE, callback); sqlite3_close(db); } ・Makefile CC=gcc CFLAGS=-Wall -g all: sample sample: sample.o $(CC) $(CFLAGS) -L/usr//local/Cellar/sqlite/3.39.0/lib/ -I/usr//local/Cellar/sqlite/3.39.0/include/ sample.o -lsqlite3 -o sample sample.o: sample.c $(CC) $(CFLAGS) -c sample.c clean: rm -f *.o sample 以下のデータがshoseki.dbに入っています。 ・sample.csv id,bookname,category,necessity,date 1,AAA,理工学,◯,2022/8/16 17:24 2,BBB,理工学,◯,2022/8/16 17:24 3,DDD,理工学,◯,2022/8/16 17:24
ソースの一番最後の部分に、gdbからブレークをかける
事ができました。
グローバル変数の構造体のsqlResultをpコマンドで確認しました。
p sqlResult
以下のエラーが発生します。
'sqlResult' has unknown type; cast it to its declared type
勉強として、構造体を確認したいです。何かいい方法は
ありますか。
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2022/08/18 11:36 編集
2022/08/18 11:45
2022/08/18 12:10
2022/08/18 12:20
2022/08/18 12:32
2022/08/18 12:45
2022/08/18 13:01
2022/08/18 13:13
2022/08/19 02:55
2022/08/19 03:18