C - 从文件中读取 - 为什么打印错误?

时间:2016-02-18 19:34:22

标签: c arrays

我正在尝试显示矩阵(墙壁被包围,内部被空格包围) 我可以默认填充它

目标是从文件中读取矩阵,并将其存储在指针中(地图)

如果insert_from_file被注释掉,你会看到它正在填充

我正在分配内存,然后为新的 ROWS&重新分配内存。列

链接到文件: http://www.filedropper.com/map1_18

但它仍然没有正确打印文件的内容。

Actual File: 

########################
#      #          #    #
#                 #  * #
#      #    M     #    #
#      #               #
### ####################
#     # M         #    #
# #####  #######  #    #
# #      #             #
# # ###  #  M       @  #
#   #    #             #
########################

The way it is printing:

########################
�#      #          #    
#�#                 #  *
 #�#      #    M     #  
  #�#      #            
   #�### ###############
#####�#     # M         
#    #�# #####  ####### 
 #    #�# #      #      
       #�# # ###  #  M  
     @  #�#   #    #    
         #�#############

以下是我可以尽可能最小的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char get(unsigned x, unsigned y);
void put(unsigned x, unsigned y, char v);
void print_map();
void populate_map();
void set_rows_cols(char const *file_name);
void insert_from_file(char const *file_name);

size_t ROWS = 10;
size_t COLS = 10;
char *map;

char get(unsigned x, unsigned y) { return *(map + (y * COLS) + x); }
void put(unsigned x, unsigned y, char v) { *(map + (y*COLS) + x) = v;}
void print_map() {
    for(int x = 0; x < ROWS; x++) {
        for(int y = 0; y < COLS; y++) {
            putchar(get(y, x));
        }
        putchar('\n');
    }
}
void populate_map() {
    for(int x = 0; x < ROWS; x++) {
        for(int y = 0; y < COLS; y++) {
            if (x == 0 || x == ROWS - 1 || y == 0 || y == COLS -1) {
                put(y, x, '#');
            } else {
                put(y, x, ' ');
            }
        }
    }
}

void set_rows_cols(char const *file_name) {
    free(map);
    FILE *file = fopen(file_name, "r");
    char mychar;
    int tempRows = 0;
    int counter = 0;

    while((mychar = fgetc(file)) != EOF) {
        if (mychar == '\n') {
            tempRows++;
        } else {
            counter++;
        }
    }
    COLS = (counter / tempRows);
    ROWS = tempRows;
    map = NULL;
    map = calloc(1000, sizeof(ROWS*COLS));
    fclose(file);
    printf("newRows: %zu\n", ROWS);
    printf("newCOLS: %zu\n", COLS);
}

void insert_from_file(char const *file_name) {
    set_rows_cols(file_name);
    FILE *myfile = fopen(file_name, "r");
    int tempR = 0;
    int tempC = 0;
    char mychar;

    for(tempR = 0; tempR < ROWS; tempR++) {
        for(tempC = 0; tempC < COLS; tempC++) {
            mychar = getc(myfile);
            if(mychar != EOF) {
                if (mychar != '\n') {
                    put(tempC, tempR, mychar);
                }
            }
        }
    }
    fclose(myfile);
}

int main(int argc, char *argv[]) {
    map = malloc(sizeof(ROWS * COLS));
    populate_map();
    insert_from_file("map1.txt");
    print_map();
}

1 个答案:

答案 0 :(得分:1)

首先,一些未定义行为的问题。您没有为map分配适当的空间:

map = malloc(sizeof(ROWS * COLS));

sizeof运算符为您提供给定数据类型的大小(以字节为单位)。在这种情况下,表达式ROWS * COLS的类型为size_t(因为这是两个操作数的类型),它在我的系统上的计算结果为8。摆脱sizeof

map = malloc(sizeof(ROWS * COLS));

同样在这里:

map = calloc(1000, sizeof(ROWS*COLS));

这实际上为1000个8字节元素分配空间。您可以使用之前执行的相同malloc命令。

现在输出问题,在这里:

for(tempR = 0; tempR < ROWS; tempR++) {
    for(tempC = 0; tempC < COLS; tempC++) {
        mychar = getc(myfile);
        if(mychar != EOF) {
            if (mychar != '\n') {
                put(tempC, tempR, mychar);
            }
        }
    }
}

当您使用换行符进行阅读时,仍然会增加tempCtempR。这就是输出偏差的原因。

只需在内部循环中进行读取,并在外部循环上执行一次额外读取以获取换行符:

for(tempR = 0; tempR < ROWS; tempR++) {
    for(tempC = 0; tempC < COLS; tempC++) {
        mychar = getc(myfile);
        put(tempC, tempR, mychar);
    }
    mychar = getc(myfile);
}