#c #parsing #file-io #multidimensional-array
#c #синтаксический анализ #file-io #многомерный массив
Вопрос:
Я изучаю C и решил создать текстовую игру в качестве своего учебного проекта. Итак, я пробую этот примитивный «анализатор», который считывает текстовый файл в 2D-массив, но есть проблема: эта карта использует не ячейки шириной в 1 символ, а ячейки шириной в 2 символа. Например, игрок представлен с помощью **
, дверь представлена как ##
и так далее.
Это означает, что мне нужно прочитать 2 символа текстового файла, а затем назначить его соответствующей ячейке на карте.
Ну, я создал тестовый файл, который содержит
aabbccddee
ffgghhiijj
kkllmmnnoo
ppqqrrsstt
uuvvwwxxyy
И я попытался прочитать его с
#include <stdio.h>
#define ROWS 5
#define COLS 5
int main() {
FILE *mapfile = fopen("durr", "r");
char charbuffer[3], row, col, *map[ROWS][COLS];
/* Initializing array */
for (row = 0; row < ROWS; row ) {
for (col = 0; col < COLS; col ) {
map[row][col] = " ";
}
}
/* Reading file into array */
for (row = 0; row < ROWS; row ) {
for (col = 0; col < COLS; col ) {
map[row][col] = fgets(charbuffer, 3, mapfile);
}
}
/* Printing array */
for (row = 0; row < ROWS; row ) {
for (col = 0; col < COLS; col ) {
printf("%s", map[row][col]);
}
printf("n");
}
fclose(mapfile);
return 0;
}
Но когда я его выполняю, я получаю это
uuuuuuuuuu
uuuuuuuuuu
uuuuuuuuuu
uuuuuuuuuu
uuuuuuuuuu
Я думаю, что это как-то связано с тем фактом, что fgets возвращает указатель, но я не уверен. Я пытался сделать это с помощью fgetc, но это выглядит неаккуратно, и я отбросил его после прочтения о gets.
Комментарии:
1. В C нет строк , только массивы символов. Следовательно, вы не можете назначить «строки» ! Вместо этого используйте
strncpy()
и убедитесь, что вы понимаете управление памятью, которое задействовано.
Ответ №1:
Вы должны были изменить содержимое, прочитанное из файла. Замените блок чтения файла этим:
/* Reading file into array */
for (row = 0; row < ROWS; row ) {
for (col = 0; col < COLS; col ) {
if (fgets(charbuffer, 3, mapfile))
map[row][col] = strdup(charbuffer);
}
}
и не забудьте также поместить это в начало вашего кода:
#include <string.h>
Комментарии:
1. Я думаю, это то, что я искал. Я искал способ (каким-то образом) разыменования возвращаемого значения fgets, но да, это то, что я искал. Теперь это вроде как работает, все странно отформатировано. Вот так pastebin.com/1F2D5zNp . Может быть, я делаю что-то не так?
2. Если идея состоит в том, чтобы выучить C, то он должен привыкать к malloc, а не вызывать функцию, которая даже не является частью стандарта.
3. Я бы сказал, это было из-за размеров массива. Не забывайте, что
fgets
не только считывает до, но и помещает EOF в буфер.4. @MattPhillips Я согласен с тем, что вы сказали. Но я также должен напомнить вам, что
POSIX
это действующий стандарт.5. О, Мэтт и Синкоу, вы правы. Думаю, мне придется выяснить, как решить эту проблему. И я родом из языков более высокого уровня, поэтому я никогда не управлял памятью вручную, поэтому я прочитаю немного больше об этом. Спасибо, ребята.
Ответ №2:
Основная проблема заключается в том, что
char *map[ROWS][COLS];
выделяет пространство только для указателей СТРОК x COLS char, оно не выделяет пространство для самих строк. Таким образом, вы постоянно перезаписываете charbuffer, как вы делали это с каждой итерацией, что объясняет, почему в итоге одни и те же символы повторяются снова и снова при чтении. Вам нужно динамически выделять необходимую вам память в соответствии с
for (row = 0; row < ROWS; row ) {
for (col = 0; col < COLS; col ) {
charbuffer = (char*)malloc(sizeof(char) * 3); //****
map[row][col] = fgets(charbuffer, 3, mapfile);
}
}
Комментарии:
1. Ха, я понимаю
incompatible implicit declaration of built-in function ‘malloc’
. Может быть, я что-то упускаю? Может ли это быть мой gcc? О, и мне пришлось изменить charbuffer[3] на *charbuffer, иначе я бы получилincompatible types when assigning to type ‘char[3] from type ‘char *’
ошибку.2. @user1002327 Правильно насчет charbuffer[3] -> charbuffer *, забыл упомянуть об этом. Что касается malloc, попробуйте #включить «stdlib.h».