C) переполнение указателя файла при fprintf () - PullRequest
2 голосов
/ 18 апреля 2020

Я новичок в программировании и сначала пытаюсь создать стек со связанным списком.

, но при печати элемента, содержащегося в списке, fprintf() не работает.

Здесь мой код:

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

//define stack and function
typedef struct element {
    int xindex;
    int yindex;
} element;

typedef struct _node {
    element value;
    struct _node *next;
    struct _node *prev;
} node;

typedef node *nptr;

typedef struct _stack {
    nptr top;
} stack;

void push(stack *sptr, element item);
element pop(stack *sptr);
void free_stack(stack *sptr);
void print_stack(node *now, FILE *fp);

int main() {
    // READ TEXT
    FILE *fp;
    fp = fopen("example.txt", "r");
    int stx, sty, fix, fiy, Maze[Maxsize][Maxsize], i, j, k;
    fscanf(fp, "%d %d\n%d %d", &sty, &stx, &fiy, &fix);

... read rest of txt...

    //build list and keep startpoint
    stack *WaysOut = (stack *)malloc(sizeof(stack));
    WaysOut->top = NULL;
    element start;
    int nowx = stx;
    int nowy = sty;
    start.xindex = nowx;
    start.yindex = nowy;
    nptr head = (nptr)malloc(sizeof(node));
    head->value = start;
    head->next = WaysOut->top;
    WaysOut->top = head;

... construct list ... 

    fflush(fp);
    fp = fopen("OUTPUT.txt", "w");
    if (WaysOut == NULL) {
        rewind(fp);
        fprintf(fp,"%s\n", "NO WAY");
    } else {
        print_stack(head, fp);
        fclose(fp);
    }

    free_stack(WaysOut);
    return 0;
}

void print_stack(node *now, FILE *fp) {
    while (now != NULL) {
        fprintf(fp, "%d %d\n", now->value.yindex - 1, now->value.xindex);
        printf("%d %d\n", now->value.yindex - 1, now->value.xindex);
        now = now->prev;
    }
    return;
}

, когда я запускаю это, 'OUTPUT.txt' создается, но ничего в тексте. Я думаю, что это связано с указателем файла fp, поскольку, когда я попробовал stdout вместо fp, он работает хорошо. Какая разница между ними вызвала это?

Спасибо.

Ответы [ 3 ]

1 голос
/ 18 апреля 2020
The problem is in this part most likely the now variable is trying to access out of 
memory.

void print_stack(node *now, FILE *fp) {
    while (now != NULL) {
        //fprintf(fp, "%d %d\n", now->value.yindex - 1, now->value.xindex);
        //printf("%d %d\n", now->value.yindex - 1, now->value.xindex);
        now = now->prev;
    }
    return;
}
0 голосов
/ 18 апреля 2020

Программа не завершена. Вероятное объяснение пустого файла OUTPUT.txt : head может быть NULL при выводе пути.

Вместо тестирования WaysOut, которое, конечно, не равно нулю, вы следует проверить WaysOut->top и передать его print_stack.

Более того, вы должны fclose(fp), когда закончите читать входной файл. fflush(fp) неверно для файла, открытого для чтения, и недостаточно для освобождения ресурсов, выделенных для указателя потока. Также закройте выходной файл, прежде чем возвращаться из main() во всех случаях, а не только в ветку else теста.

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

Также обратите внимание, что это сбивает с толку и склонно к ошибкам скрывать указатели за typedefs. Лучше сделать эти указатели явными.

Вот модифицированная версия:

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

//define stack and function
typedef struct element {
    int xindex;
    int yindex;
} element;

typedef struct node {
    element value;
    struct node *next;
    struct node *prev;
} node;

typedef struct _stack {
    node *top;
} stack;

void push(stack *sptr, element item);
element pop(stack *sptr);
void free_stack(stack *sptr);
void print_stack(node *now, FILE *fp);

int main() {
    // READ TEXT
    FILE *fp;
    fp = fopen("example.txt", "r");
    if (fp == NULL) {
        printf("cannot open example.txt\n");
        return 1;
    }
    int stx, sty, fix, fiy, Maze[Maxsize][Maxsize], i, j, k;

    fscanf(fp, "%d %d\n%d %d", &sty, &stx, &fiy, &fix);

    ... read rest of txt...

    fclose(fp);

    //build list and keep startpoint
    stack *WaysOut = malloc(sizeof(stack));
    if (WaysOut == NULL) {
        printf("cannot allocate WaysOut\n");
        return 1;
    }
    WaysOut->top = NULL;
    element start;
    int nowx = stx;
    int nowy = sty;
    start.xindex = nowx;
    start.yindex = nowy;
    node *head = malloc(sizeof(node));
    if (head == NULL) {
        printf("cannot allocate head\n");
        return 1;
    }
    head->value = start;
    head->next = WaysOut->top;
    WaysOut->top = head;

    ... construct list ... 

    fp = fopen("OUTPUT.txt", "w");
    if (fp == NULL) {
        printf("cannot open OUTPUT.txt\n");
        return 1;
    }
    if (WaysOut->top == NULL) {
        fprintf(fp, "%s\n", "NO WAY");
        printf("%s\n", "NO WAY");
    } else {
        print_stack(WaysOut->top, fp);
    }
    fclose(fp);

    free_stack(WaysOut);
    return 0;
}

void print_stack(node *np, FILE *fp) {
    while (np != NULL) {
        fprintf(fp, "%d %d\n", np->value.yindex - 1, np->value.xindex);
        printf("%d %d\n", np->value.yindex - 1, np->value.xindex);
        np = np->prev;
    }
}
0 голосов
/ 18 апреля 2020
fflush(fp)

до

fp = fopen("OUTPUT.txt","w");

является проблемой. Вы должны звонить fclose(fp) вместо fflush(fp), если хотите повторно использовать fp. Также вызовите fclose(fp) перед возвратом.

Или вы можете использовать другую переменную

FILE *fp1 = fopen("OUTPUT.txt","w");

, а затем вызовите fclose(fp1) перед возвратом.

...