2016-05-18 1 views
-3

У меня есть структура «book», содержащая автора, имя и количество доступных книг.Нарушение прав доступа при записи struct в файл

struct book { 
    TCHAR author[32]; 
    TCHAR name[32]; 
    SHORT count; 
    void insert() { 
     cout << "Book author: "; wscanf_s(L"%s", author, _countof(author)); 
     cout << "Book name: "; wscanf_s(L"%s", name, _countof(name)); 
     cout << "Book count: "; wscanf_s(L"%i", count); 
    } 
    void get() { 
     cout << "Book info: " << endl; 
     wprintf(L"\nAuthor - %s", author); 
     wprintf(L"\nName - %s", name); 
     wprintf(L"\nCount - %i", count); 
     cout << endl; 
    } 
}; 

Задача заставила меня создать файл DAT, а затем добавить в него «книги».

HANDLE hFile = CreateFile(_TEXT("C:\\Students\\book.dat"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
SetFilePointer(hFile, 0, 0, FILE_END); 
book newBook; 
DWORD bytesWritten; 
newBook.insert(); 
WriteFile(hFile, &newBook, sizeof(book), &bytesWritten, NULL); 
FindClose(hFile); 

Однако всякий раз, когда я делаю это, я получаю сообщение об ошибке:

Access violation writing location 0xFFFFFEFE.

Что я здесь делаю неправильно?

+0

Вы действительно должны проверять возвращаемые значения из _all_ этих вызовов API, чтобы убедиться, что все работает. – theB

+0

Помимо ошибки scanf, вы выполняете проверку ошибок, вы используете TCHAR, который давно устарел, вы используете необработанный Win32 IO, а не C++ IO, и записываете неинициализированную структуру. –

+0

Я должен использовать исходные методы Win32, когда это возможно. Я бы не использовал их, если бы у меня был выбор. Будет добавлена ​​проверка ошибок. – VCib

ответ

0

Эта линия

cout << "Book count: "; wscanf_s(L"%i", count); 

должен быть

cout << "Book count: "; wscanf_s(L"%i", &count); 

Вы, вероятно, следует также проверить, что файл открыт:

HANDLE hFile = CreateFile(_TEXT("C:\\Students\\book.dat"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
if (hFile == INVALID_HANDLE_VALUE) { 
    cerr << "Unable to open file\n"; 
    exit(1); 
} 

--- Edit ---

С вашим кодом as-is Visual Stud ИО дает следующие предупреждения:

c:\dev\test\test.cpp(14): warning C4477: 'wscanf_s' : format string '%i' requires an argument of type 'int *', but variadic argument 1 has type 'SHORT *'

c:\dev\test\test.cpp(14): note: consider using '%hi' in the format string

Что это означает, что

cout << "Book count: "; wscanf_s(L"%i", &count); 

должен быть

cout << "Book count: "; wscanf_s(L"%hi", &count); 

или вы должны посчитать DWORD.

+0

Изменено, добавлено. Теперь читается: Исключение первого шанса в 0x77D22312 (ntdll.dll) в SysLab4.exe: 0xC0000005: место записи нарушения доступа 0xFEFEFF1E. – VCib

+0

Вы игнорируете предупреждения компилятора или не открываете окно вывода? – kfsone

+0

@VCib См. Править. – kfsone

0

Нарушение прав доступа связано с тем, что вы вызываете FindClose на ручке, открытой с помощью CreateFile. FindClose предназначен только для закрывающих ручек, полученных через FindFirstFile.

Вместо этого необходимо позвонить по телефону CloseHandle.

Смежные вопросы