Ошибка сегментации при вызове fread () c ++

0

Я не понимаю, какую ошибку я делаю. Я пробовал много, но я не могу прочитать свой ФАЙЛ. В основном я пишу структуру в файл с именем 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.

  • 0
    I realy seached hours to fix my problem Когда вы вызываете функции, которые могут возвращать успех или неудачу, вы должны проверить возвращаемое значение. Вы вызвали fopen без проверки возвращаемого значения - не хорошо.
Теги:
segmentation-fault
fread

3 ответа

3

причина

Скорее всего, вы вызываете fread на дескриптор файла NULL. Итак, у вас есть две проблемы:

  1. В вашем коде (вы не проверяете, успешно ли fread или возвращает значение NULL)
  2. По какой-либо причине ваш файл не может быть открыт (это вам следует изучить...)

экспликация

fopen (см. документацию) может возвращать дескриптор NULL по разным причинам. Если вы не проверяете действительность дескриптора перед вызовом fread вас будет ошибка сегментации.

Советы

Как вы можете прочитать в официальной документации, связанной выше, в большинстве реализаций библиотек переменная errno может помочь вам при сбое системного кода ошибки. Это может помочь вам отладить вашу ошибку при открытии файла.

Боковые проблемы

Как только вы решите эту ошибку в нашем коде, у вас появятся другие проблемы. Как отмечают другие пользователи, в отличие от @Christophe, в вашем коде есть структурная проблема, потому что вы пытаетесь сериализовать/десериализовать свои файловые объекты, не являющиеся POD (иначе ваши строки). Поскольку строка - это сложные объекты, вы не можете их сериализовать напрямую.

Подход к использованию массива символов будет работать правильно, так как простые типы могут обрабатываться так, как вы кодировали.

По этой причине вы можете использовать метод std::string c_str(), чтобы получить нулевой конец массива символов из вашей строки и сохранить его в файле.

Противоположная операция еще более проста, так как вы можете инициализировать std :: string, просто передавая десериализованный массив символов:

std::string str(the_array);
  • 0
    Спасибо, я сделаю некоторые тесты, вероятно, есть проблема с путем к файлу или что-то.
  • 0
    @ spyce14 Рад помочь. В качестве примечания, пожалуйста, прочитайте также ответ Кристофа: у вас есть другие проблемы в вашем коде, особенно тот факт, что вы пытаетесь вставить / прочитать не POD- строки в / из файла.
1

У вас проблема, потому что вы используете fread() для загрузки двоичных данных. Но это работает только с объектами с обычными старыми данными (POD).

Он использует, чтобы дать разрушительные результаты с менее тривиальными объектами, особенно если их внутренние элементы управляют распределением динамической памяти и/или указателями, как это имеет место здесь со строками.

Кстати:

Если вы читаете/записываете двоичные данные, вы действительно должны использовать "rb"/"wb" в качестве режима для fopen(). Если вы этого не сделаете, вам не понадобится seg.fault, но ваши данные могут быть неверными в некоторых системах.

Редактировать:

Извините, я не читал достаточно хорошо: если это происходит прямо на fread() то причина, по которой Алекс может помочь. Однако я оставляю этот ответ, потому что, как только вы решите проблему fopen(), вы можете получить ошибки сегментации, если попытаетесь работать с объектом, который вы прочитали. Если вы не уверены, посмотрите на sizeof(iAccount) и сравните его с размером строкового содержимого.

  • 1
    Ошибка сегментации, возникающая на fread , не имеет к этому никакого отношения. @ spyce14 сказал, что infoma - это экземпляр структуры, я не понимаю, как из-за этого fread может возникнуть ошибка сегментации ...
  • 1
    Я не знаю, является ли это причиной рассматриваемой аварии, но это действительно реальная проблема. Экземпляры std::string не являются массивами. fread забьет их. Носовые демоны повсюду.
Показать ещё 2 комментария
0

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);    
}

Там у меня нет проблем!

  • 0
    Пожалуйста, добавьте это как редактирование вопроса, а не как ответ ...
  • 0
    @AlexGidan Извините, мой бад ...
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню