Я новичок в программировании на C и пытаюсь правильно понять все тонкости управления памятью в C.
Я сделал простую программу, которая компилируется без проблем, но при отладке выдает ошибку сегментации после строки printf("The next line gives a segmentation error");
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // Here you have the isdigit macro
int main()
{
FILE *filePtr;
char fileStr[150]; // Buffer for reading file.
filePtr = fopen("ManyRandomNumbersLog.txt", "r");
printf("\n\nNow reading the file:\n");
while (!feof(filePtr))
{
printf("The next line is a segmentation fault!\n");
// WHYYYY?!?!?!?
fgets(fileStr, 150, filePtr);
printf("%s\n", fileStr);
}
return 0;
}
Вызов функции fgets, похоже, выдает эту ошибку, поскольку указатель имеет следующую «ошибку?» внутри него:
Вы знаете, в чем проблема и как ее предотвратить?
Я попытался отладить его, но не мог понять, почему указатель не может получить доступ к этой памяти.





Всегда проверяйте, успешно ли был открыт файл. Также feof не работает так, как вы думаете.
int main()
{
FILE* filePtr;
char fileStr[150]; // Buffer for reading file.
filePtr = fopen("ManyRandomNumbersLog.txt","r");
if (filePtr)
{
printf("\n\nNow reading the file:\n");
while(fgets(fileStr, 150, filePtr))
{
printf("%s\n",fileStr);
//filestr will also contain '\n' at the end if it was present in the file.
}
fclose(filePtr);
}
return 0;
}
PS не заглядывайте внутрь структуры FILE, так как это не даст вам никакой ценной информации.
Вы всегда должны проверять потенциальный сбой fopen() и сообщать об этом со значимой информацией:
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main()
{
FILE *filePtr = fopen("ManyRandomNumbersLog.txt", "r");
if (filePtr == NULL) {
fprintf(stderr, "cannot open file %s: %s\n",
"ManyRandomNumbersLog.txt", strerror(errno));
return 1;
}
printf("\n\nNow reading the file:\n");
char fileStr[150]; // Buffer for reading file.
// Do not use feof() for this loop:
// just try and read a line and stop upon failure to do so.
while (fgets(fileStr, 150, filePtr)) {
printf("%s\n", fileStr);
}
fclose(filePtr);
return 0;
}
Как ни странно, fopen() не требуется устанавливать errno при сбое. Однако большинство реализаций IME устанавливают его. И это означает, что fopen() может свободно трахаться errno, когда он не терпит неудачу...
@AndrewHenle: я думаю, это проблема качества реализации.
Всегда проверяйте, был ли файл открыт, прежде чем каким-либо образом использовать указатель.
if (filePtr) { ... }и прочитайте Почему «пока( !feof(file) )» всегда неправильно?