#c #scanf
#c #scanf
Вопрос:
Я хочу прочитать файл в определенном формате, поэтому я использую fscanf_s и цикл while. Но как только fscanf_s обрабатывается, программа завершает работу с нарушением доступа (0xC0000005).
Вот код:
FILE *fp;
errno_t err = fopen_s(amp;fp, "C:\data.txt", "r");
if (err != 0)
return 0;
int minSpeed = 0;
int maxSpeed = 0;
char axis = '@';
while(!feof(fp))
{
int result = fscanf_s(fp, "%c;%d-%dn", amp;axis, amp;minSpeed, amp;maxSpeed);
if (result != 3)
continue;
}
fclose(fp);
Содержимое файла основано на строках, например:
-;10000-20000
X;500-1000
S;2000-2400
Кто-нибудь может мне помочь?
Комментарии:
1. Что? нет
feof_s()
илиfclose_s()
? Действительно,*_s
функции хуже, чем функции с простыми именами: они требуют тех же проверок и позволяют вам чувствовать себя в безопасности, когда вы этого не делаете. Я предлагаю вам не использовать их из-за ложного чувства безопасности и того факта, что они недоступны во многих реализациях, из-за чего ваши программы работают только на ограниченном подмножестве возможных компьютеров.2. @pmg Я не использую feof_s amp; fclose_s, потому что они не определены. Но удаление этого _s из fscanf_s сделало свое дело. Теперь это работает! 🙂 Спасибо!
3. Да, у меня возникла та же проблема, когда я попробовал небольшую тестовую программу. Странные это маленькие функции!
4.
feof_s()
иfclose_s()
были шуткой (смехотворно); по-видимому, правильный вызов fscanf_s() был быfscanf_s(fp, "%c;%d-%dn", amp;axis, 1, amp;minSpeed, amp;maxSpeed);
с дополнительным значением1
для размераaxis
«массива». Не используйте*_s
функции!5. @pmg: вы должны указать это в качестве ответа 🙂
Ответ №1:
По-видимому, fscanf_s()
требуется параметр размера после адреса переменной
fscanf_s(fp, "%c;%d-%dn", amp;axis, 1, amp;minSpeed, amp;maxSpeed);
/* extra 1 for the size of the ^^^ axis array */
Но я предлагаю вам не использовать *_s
функции: они хуже, чем функции с простыми именами — они требуют тех же проверок и позволяют вам чувствовать себя в безопасности, когда вы этого не делаете. Я предлагаю вам не использовать их из-за ложного чувства безопасности и того факта, что они недоступны во многих реализациях, из-за чего ваши программы работают только на ограниченном подмножестве возможных компьютеров.
Используйте обычный fscanf()
fscanf(fp, "%c;%d-%dn", amp;axis, amp;minSpeed, amp;maxSpeed);
/* fscanf(fp, ";%d-%dn", amp;axis, amp;minSpeed, amp;maxSpeed); */
/* default 1 ^^^ same as for fscanf_s */
И ваше использование feof()
неверно.
fscanf()
Возвращает EOF при возникновении ошибки (ошибка конца файла или сопоставления или ошибка чтения …).
Вы можете использовать, feof()
чтобы определить причину fscanf()
сбоя, а не проверять, произойдет ли сбой при следующем вызове.
/* pseudo-code */
while (1) {
chk = fscanf();
if (chk == EOF) break;
if (chk < NUMBER_OF_EXPECTED_CONVERSIONS) {
/* ... conversion failures */
} else {
/* ... all ok */
}
}
if (feof()) /* failed because end-of-file reached */;
if (ferror()) /* failed because of stream error */;
Ответ №2:
Если вы считаете, что файл (data.txt ) существует, ваше приложение, вероятно, не запущено с текущим каталогом, установленным в том месте, где находится файл. Это привело бы к сбою функции fopen_s().
Комментарии:
1. Верно, но fopen_s выполняется успешно, я проверил это в отладчике Visual studio.