Предполагая, что вы еще не заработали, просмотр кода в вашем вопросе заставляет меня подозревать, что вы еще не настолько сильны в C, потому что есть некоторые странные моменты, которые на самом деле не имеют никакого смысла (ПочемуВы читаете строку с fgets()
, а затем сразу же используете fscanf()
для чтения одного слова в ту же переменную, в которую вы только что прочитали строку? Особенно, когда ваш ввод имеет одно имя файла на строку? И что memcpy () будетсломаться, если вы попытаетесь использовать файлы в разных каталогах.)
Вот почему я предложил использовать сценарий оболочки.Со всей вашей информацией в файлах, это будет намного проще, даже если вы свободно говорите на C.
Вот пример, относящийся к bash:
#!/bin/bash
database=test.db
domainsfile=domainlist.txt
coproc sqlite3 -batch -list "$database"
echo "PRAGMA journal_mode = TRUNCATE;" >&${COPROC[1]}
while read filename; do
d=$(dirname "$filename")
tablename=$(basename "$d")
cat >&${COPROC[1]} <<EOF
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "$tablename"(url TEXT);
.import "$filename" "$tablename"
COMMIT;
EOF
done <$domainsfile
echo .quit >&${COPROC[1]}
wait $COPROC_PID
и менее эффективный (потому чтозапускает новый экземпляр оболочки sqlite3 для каждой таблицы вместо использования одного для всех из них), но более универсальную переносимую версию sh:
#!/bin/sh
database=test.db
domainsfile=domainlist.txt
while read filename; do
d=$(dirname "$filename")
tablename=$(basename "$d")
sqlite3 -batch -list "$database" <<EOF
CREATE TABLE IF NOT EXISTS "$tablename"(url TEXT);
.import "$filename" "$tablename"
EOF
done <$domainsfile
Однако некоторые подсказки для версии C:
Для каждого имени файла в domainlist.txt извлеките часть имени таблицы (было бы полезно использовать функции POSIX dirname()
и basename()
).Затем создайте таблицу с чем-то вроде:
char *errmsg;
char *table_stmt = sqlite3_mprintf("CREATE TABLE \"%s\"(url TEXT);", tablename);
if (sqlite3_exec(db, table_stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
// Error handling
}
sqlite3_free(table_stmt);
и импортируйте содержимое текущего файла с чем-то вроде:
char *insert_stmt = sqlite3_mprintf("INSERT INTO \"%s\"(url) VALUES (?)", tablename);
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, insert_stmt, -1, &stmt, NULL) != SQLITE_OK) {
// Error handling
}
// Open the current file
// In a loop that reads each line in it:
sqlite3_bind_text(stmt, 1, line, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) != SQLITE_DONE) {
// Error handling
}
sqlite3_reset(stmt);
// After importing the file:
sqlite3_finalize(stmt);
Возможно, вы захотите обернуть каждый импорт таблицы втранзакция, как в примере с bash, или даже вся эта вещь по соображениям производительности.