Я не понимаю, какую ошибку я делаю. Я пробовал много, но я не могу прочитать свой ФАЙЛ. В основном я пишу структуру в файл с именем 0.txt/1.txt/2.txt... на основе amound. Я действительно провел время, чтобы исправить мою проблему, но я не понимаю, как я могу это исправить, и почему я получаю ОШИБКУ. Также у меня нет проблем с тем, чтобы скомпрометировать мой код (с помощью dev c++), но когда я нажимаю кнопку Load Accounts, я получаю ERROR " Segmentation Faul t" (используя Windows 7). Я заметил, что проблема в строке fread() в функции ladeAccounts(). Имя моей структуры - "iAccount". Переменная infoma соответствует типу iAccount и "количеству существующих учетных записей", введенному как int anzahl в newAccount(), решает путь.
iAccount выглядит так:
struct iAccount
{
string ID;
string password;
int level;
};
Вот как я пишу свою СТРУКТУЮ в ФАЙЛ:
void Account::newAccount(int anzahl, string username, string pw, int lvl)
{
iAccount neu;
neu.ID = username;
neu.password = pw;
neu.level = lvl;
ss.str("");
ss<<anzahl;
s = ss.str();
s = "Accounts/"+s+".txt";
f1 = fopen(s.c_str(), "w");
fseek(f1, 0, SEEK_SET);
fwrite(&infoma, sizeof(iAccount), 1, f1);
fclose(f1);
}
Вот как я читаю файл (ОШИБКА ЯВЛЯЕТСЯ, когда я вызываю fread()
void Account::ladeAccount(int nummer)
{
stringstream sa;
iAccount account_geladen;
sa.str("");
sa<<nummer;
s = sa.str();
s = "Accounts/"+s+".txt";
f2 = fopen(s.c_str(), "r");
fseek(f2, 0, SEEK_SET);
fread(&infoma, sizeof(infoma), 1, f2);
fclose(f2);
}
Спасибо за помощь. Я не знаю, где моя проблема, и, как я уже сказал, я ищу часы.
EDIT: файл открывается. Я попробовал его (f2 верно!).
EDIT ": ERRNO = 0 !!!
ГЛЯНЬ СЮДА:
ostringstream Str;
Str << errno;
infoma.ID = Str.str();
Просто сделал это, чтобы увидеть результат errno в моей wxtextlabel.
Скорее всего, вы вызываете fread
на дескриптор файла NULL
. Итак, у вас есть две проблемы:
fread
или возвращает значение NULL
) fopen
(см. документацию) может возвращать дескриптор NULL
по разным причинам. Если вы не проверяете действительность дескриптора перед вызовом fread
вас будет ошибка сегментации.
Как вы можете прочитать в официальной документации, связанной выше, в большинстве реализаций библиотек переменная errno
может помочь вам при сбое системного кода ошибки. Это может помочь вам отладить вашу ошибку при открытии файла.
Как только вы решите эту ошибку в нашем коде, у вас появятся другие проблемы. Как отмечают другие пользователи, в отличие от @Christophe, в вашем коде есть структурная проблема, потому что вы пытаетесь сериализовать/десериализовать свои файловые объекты, не являющиеся POD (иначе ваши строки). Поскольку строка - это сложные объекты, вы не можете их сериализовать напрямую.
Подход к использованию массива символов будет работать правильно, так как простые типы могут обрабатываться так, как вы кодировали.
По этой причине вы можете использовать метод std::string
c_str(), чтобы получить нулевой конец массива символов из вашей строки и сохранить его в файле.
Противоположная операция еще более проста, так как вы можете инициализировать std :: string, просто передавая десериализованный массив символов:
std::string str(the_array);
У вас проблема, потому что вы используете fread()
для загрузки двоичных данных. Но это работает только с объектами с обычными старыми данными (POD).
Он использует, чтобы дать разрушительные результаты с менее тривиальными объектами, особенно если их внутренние элементы управляют распределением динамической памяти и/или указателями, как это имеет место здесь со строками.
Кстати:
Если вы читаете/записываете двоичные данные, вы действительно должны использовать "rb"/"wb" в качестве режима для fopen()
. Если вы этого не сделаете, вам не понадобится seg.fault, но ваши данные могут быть неверными в некоторых системах.
Редактировать:
Извините, я не читал достаточно хорошо: если это происходит прямо на fread()
то причина, по которой Алекс может помочь. Однако я оставляю этот ответ, потому что, как только вы решите проблему fopen()
, вы можете получить ошибки сегментации, если попытаетесь работать с объектом, который вы прочитали. Если вы не уверены, посмотрите на sizeof(iAccount)
и сравните его с размером строкового содержимого.
fread
, не имеет к этому никакого отношения. @ spyce14 сказал, что infoma
- это экземпляр структуры, я не понимаю, как из-за этого fread
может возникнуть ошибка сегментации ...
std::string
не являются массивами. fread
забьет их. Носовые демоны повсюду.
EDIT, если (f2) истинно, поэтому я ошибаюсь, и файл был открыт успешно?
Я узнал, что файл не открывается /fopen не может обрабатывать путь, например 0.txt. Также я попытался войти в путь напрямую, не создавая его (без stringstream и т.д.). Тем не менее у меня проблема с ошибкой сегментации. Я проверил все, что существует в папке "Учетные записи". У меня есть другой файл под названием "Accounts.txt" в той же папке, и там у меня нет проблем с чтением амунированных учетных записей (также с использованием структуры). Там я даже не проверял, успешно ли fopen, но он работает, я напишу код для проверки файла позже.
Код для чтения/записи в Accounts/Accounts.txt:
struct init{
int anzahl_1;};
init anzahl;
FILE* f;
static string ss = "Accounts/Accounts.txt";
int account_anzahl1()
{
f = fopen(ss.c_str(), "r");
fread(&anzahl, sizeof(init), 1, f);
fseek(f, 0, SEEK_END);
fclose(f);
return anzahl.anzahl_1;
}
void account_anzahl_plus()
{
anzahl.anzahl_1 = anzahl.anzahl_1 +1;
f = fopen(ss.c_str(), "w");
fwrite(&anzahl, sizeof(init), 1, f);
fclose(f);
}
Там у меня нет проблем!
I realy seached hours to fix my problem
Когда вы вызываете функции, которые могут возвращать успех или неудачу, вы должны проверить возвращаемое значение. Вы вызвалиfopen
без проверки возвращаемого значения - не хорошо.