Intereting Posts
Как разрешить две структуры с тем же именем? Есть ли стандартная версия strcpy? == для сравнения указателей Как исправить мой код Pthreads о наборе Мандельброта? Существует ли оптимальный размер байта для отправки данных по сети? в каких ситуациях следует использовать анонимное перечисление? Определение дня недели с использованием конгруэнтности Целлера ImportError и PyExc_SystemError при вложении Python Script в C для модhive PAM (файлы .so) Вставка данных в файл в c Почему timer_create throw error для SIGEV_THREAD в Solaris 10? Можно ли использовать C11-ограждения, чтобы рассуждать о записи из других streamов? Как преобразовать римские цифры в int при отказе от недопустимых чисел с помощью стандартного C? Lex: идентификатор и целое число Удаление элемента из таблицы (c) Могут ли все функции в streamе иметь доступ к динамически распределенной памяти (куче) даже без указания указателя или локально для функции?

Чтение символа файла символом в C

Привет всем, я пишу интерпретатор BF в C, и я столкнулся с проблемой чтения файлов. Раньше я использовал scanf для чтения первой строки, но тогда у вас не могло быть пробелов или комментариев в вашем BF-коде.

Прямо сейчас вот что у меня есть.

char *readFile(char *fileName) { FILE *file; char *code = malloc(1000 * sizeof(char)); file = fopen(fileName, "r"); do { *code++ = (char)fgetc(file); } while(*code != EOF); return code; } 

Я знаю, что проблема возникает в том, как я назначаю следующий символ в файле указателю кода, но я просто не уверен, что это такое.
Знаний моего указателя не хватает, что является точкой этого упражнения. Интерпретатор работает нормально, все с помощью указателей, у меня просто проблема с чтением файлов.

(Я собираюсь реализовать только чтение «+ -> <[].,» В файл позже, хотя, если у кого есть хороший способ сделать это, было бы здорово, если бы вы сообщили мне!)

заранее спасибо

В коде есть ряд ошибок:

 char *readFile(char *fileName) { FILE *file; char *code = malloc(1000 * sizeof(char)); file = fopen(fileName, "r"); do { *code++ = (char)fgetc(file); } while(*code != EOF); return code; } 
  1. Что делать, если файл больше 1000 байтов?
  2. Вы увеличиваете code каждый раз, когда вы читаете символ, и возвращаете code обратно вызывающему (хотя он больше не указывает на первый байт блока памяти, поскольку он был возвращен malloc ).
  3. Вы передаете результат fgetc(file) в char . Вам нужно проверить EOF перед тем, как отправить результат на char .

Важно сохранить исходный указатель, возвращаемый malloc чтобы вы могли его освободить позже. Если мы будем игнорировать размер файла, мы сможем достичь этого:

 char *readFile(char *fileName) { FILE *file = fopen(fileName, "r"); char *code; size_t n = 0; int c; if (file == NULL) return NULL; //could not open file code = malloc(1000); while ((c = fgetc(file)) != EOF) { code[n++] = (char) c; } // don't forget to terminate with the null character code[n] = '\0'; return code; } 

Существуют различные системные вызовы, которые дадут вам размер файла; общий – stat .

Расширяя вышеуказанный код от @dreamlax

 char *readFile(char *fileName) { FILE *file = fopen(fileName, "r"); char *code; size_t n = 0; int c; if (file == NULL) return NULL; //could not open file fseek(file, 0, SEEK_END); long f_size = ftell(file); fseek(file, 0, SEEK_SET); code = malloc(f_size); while ((c = fgetc(file)) != EOF) { code[n++] = (char)c; } code[n] = '\0'; return code; } 

Это дает вам длину файла, затем переходит к чтению символа по символу.

Я думаю, что самая значительная проблема заключается в том, что вы увеличиваете code при чтении файлов, а затем возвращаете окончательное значение code , то есть вы будете возвращать указатель в конец строки. Вероятно, вы захотите сделать копию code перед циклом и вместо этого вернете это.

Кроме того, строки C должны иметь нулевое завершение. Вам нужно убедиться, что вы разместили '\0' непосредственно после последнего символа, который вы читали.

Примечание. Вы можете просто использовать fgets() чтобы получить всю строку за один удар.

Вот один простой способ игнорировать все, кроме действительных символов мозгового мозга:

 #define BF_VALID "+-><[].," if (strchr(BF_VALID, c)) code[n++] = c; 

файл открывается и не закрывается для каждого вызова функции также

Любой из двух должен сделать трюк –

 char *readFile(char *fileName) { FILE *file; char *code = malloc(1000 * sizeof(char)); char *p = code; file = fopen(fileName, "r"); do { *p++ = (char)fgetc(file); } while(*p != EOF); *p = '\0'; return code; } char *readFile(char *fileName) { FILE *file; int i = 0; char *code = malloc(1000 * sizeof(char)); file = fopen(fileName, "r"); do { code[i++] = (char)fgetc(file); } while(code[i-1] != EOF); code[i] = '\0' return code; } 

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

Проблема здесь двоякая: а) вы увеличиваете указатель до того, как вы проверите значение, считанное, и b) вы игнорируете тот факт, что fgetc () возвращает int вместо char.

Первое легко фиксируется:

 char *orig = code; // the beginning of the array // ... do { *code = fgetc(file); } while(*code++ != EOF); *code = '\0'; // nul-terminate the string return orig; // don't return a pointer to the end 

Вторая проблема более тонкая – fgetc возвращает int sonthat значение EOF можно отличить от любого возможного значения chsr. Для этого используется временный int для проверки EOF и, вероятно, регулярный цикл while вместо do / while.