Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

c - Trouble reading file into 2d array with getc

Evening, I'm having trouble getting a file to read into a 2d array that I've allocated (maze[][]). The 2d array is allocated and sized according to the max rows (number of lines) and max columns (line with longest number characters). I'm using getc, but I'm thinking it very limited on its uses and may need an alternative way of successfully getting my array up. In the file there are newlines that end earlier than the max column and I figure that may be throwing off copying the file into my array. If a file is sized perfectly it works perfectly though.

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

#define MAX_LINE_SIZE 256

char **get_maze_map(char *argv[], int *rows, int *columns);
char **alloc_maze(char **maze, int *rows, int *columns);
void print_maze_map(char **maze, const int *rows, const int *columns);
void destroy_maze_map(char **maze, const int *rows);

int main(int argc, char *argv[])
{
    if (argc == 2) {
        int rows = 0;
        int columns = 0;

        char **maze = get_maze_map(argv, &rows, &columns);

        print_maze_map(maze, &rows, &columns);

        destroy_maze_map(maze, &rows);


    }




    else {
        printf("
USAGE ERROR: ./maze [filename].txt");
        exit(-1);
    }


    return 0;
}

void print_maze_map(char **maze, const int *rows, const int *columns)
{
    int i;
    int j;
    for (i = 0; i < *rows; ++i) {
        for (j = 0; j < *columns; ++j) {
            printf("%c", maze[i][j]);
        }
        printf("
");
    }
    printf("
");
}

void destroy_maze_map(char **maze, const int *rows)
{
    for (int i = 0; i < *rows; ++i) {
        free(maze[i]);
    }
    free(maze);
}

char **get_maze_map(char **argv, int *rows, int *columns)
{
    FILE *fp = fopen(argv[1], "r");
    if (!fp) {
        fprintf(stderr, "
Could not open %s", argv[1]);
        exit(-1);
    }

    char *line_buf = NULL;
    size_t line_buf_size = 0;
    int line_count = 0;
    ssize_t line_size;

    line_size = getline(&line_buf, &line_buf_size, fp);

    while (line_size >= 0)
    {
        line_count++;

        printf("line[%06d]: chars=%06zd, buf size=%06zu, contents: %s", line_count,
               line_size, line_buf_size, line_buf);

        line_size = getline(&line_buf, &line_buf_size, fp);

        if (line_size > *columns) {
            *columns = line_size;
        }
    }
    *rows = line_count;
    free(line_buf);
    line_buf = NULL;


    (*columns)--;
    printf("
Rows %d", *rows);
    printf("
Columns %d", *columns);
    printf("
");

    char **maze = malloc(*rows * sizeof(char*));

    for (int i = 0; i < *rows; ++i){
        maze[i] = malloc(*columns * sizeof(char*));
    }

    int a;
    int b;
    for (a = 0; a < *rows; ++a) {
        for (b = 0; b < *columns; ++b) {
            maze[a][b] = ' ';
        }
    }

    rewind(fp);

    int i;
    int j;
    char c;



    for (i = 0; i < *rows; ++i) {
        for (j = 0; j < *columns; ++j) {

            if ((c = getc(fp)) == '
') {
                c = getc(fp);
            }

            maze[i][j] = c;
        }
    }

    fclose(fp);

    return maze;
}
#############################################################################  
#   #########################################################       #########  
# >              ##########       ######   ##################       #########  
#   #######           #####                ###                              ## 
###########      #### #####       ### ##   ###    ###########       #######  # 
###########      ####             ### ##          ########################## # 
###########      #######################   ###    ########################## # 
###########################       ### ########    #######               ###  # 
##                         # #### ### #### ##############        ######     #  
## #######################   ####                         # ############### #  
##          #################################################################  
##          #                                                                  
##          #                                                                  
##          #################################################################  
########### ##########    ## ####       ## ######                  ######## #  
########### ##########       #### ##    ## ######      #### #      ######## #  
########### ################ #### ##    ## ######      #### #      ######## #  
########      ############## #### ##    ## ################ #      ######## #  
########                     #### ##    ## ################ #      ######## #  
####   #      ################### #######                   #      ######## #  
####   ### #######           #### ####### ###################      ######## #  
###### ### ####### #########      ####### ##      ###########      ######## #  
######     ####### ##############       # ##      ############# ########### #  
##########             ################           #############    @        #  
#############################################################################  
################################################################################
#   ############################################################       #########
# > #######      ##########       #########   ##################       #########
#   #######           #####           #####   ###                              #
## ########      #### #####       ### #####   ###    ###########       ####### #
## ########      ####             ### #####   ###    ######################### #
## ########      ##########       ### #####   ###    ######################### #
## ########################       ### ####### ###    #######               ### #
## ######################### ######## ####### ##############        ######     #
## ######################### ####     ####### ################ ############### #
##          ################ #### ########### ################ ############### #
########### ##########    ## #### ########### ######           #    @ ######## #
########### ##########    ## #### ########### ###### ######### #      ######## #
########### ##########    ## ####          ## ######      #### #      ######## #
########### ##########       #### ##       ## ######      #### #      ######## #
########### ################ #### ##       ## ######      #### #      ######## #
########      ############## #### ##       ## ################ #      ######## #
########                     #### ##       ## ################ #      ######## #
####   #      ################### ##########                   #      ######## #
####   ### #######           #### ########## ###################      ######## #
###### ### ####### #########      ########## ##      ###########      ######## #
######     ####### ##############          # ##      ############# ########### #
#################      ###################           ############# ########### #
#################      ###########################################             #
################################################################################
question from:https://stackoverflow.com/questions/65948747/trouble-reading-file-into-2d-array-with-getc

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your main reading loops are:

for (i = 0; i < *rows; ++i) {
    for (j = 0; j < *columns; ++j) {
        if ((c = getc(fp)) == '
') {
            c = getc(fp);
        }
        maze[i][j] = c;
    }
}

When you get a newline early, you should put blanks to the full width, or just start on the next row of data, rather than just continuing with the first character of the next line at the end of the current line. Something along the lines of:

for (int i = 0; i < *rows; ++i)
{
    for (int j = 0; j < *columns; ++j)
    {
        if ((c = getc(fp)) == '
')
        {
            while (j < *columns)
                map[i][j++] = ' ';
            break;
        }
        maze[i][j] = c;
    }
    if (c != '
')
    {
        /* This loop should execute at most once */
        while ((c = getc(fp)) != EOF && c != '
')
            ;
    }
}

Should the lines be null-terminated? Should calls to getc() be checked for EOF more frequently?

Warning: untested code!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...