Не читаете номер правильно? - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь читать из файла построчно. Он занимает первый номер строки, а остальные соединяет его, используя символ связанного списка. Но когда я запускаю его, я получаю соединение как -38 (что неверно), и оно печатает его только один раз и не проходит через остальную часть строки. но он отлично читает первый элемент.

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

struct node{
    int data;
    struct node* next;
};


int main(void)
{
    FILE * fp;
    char * line = NULL;
    char * storage;
    size_t len = 0;
    ssize_t read;
    struct node *G[1000];
    for (int i = 1; i < 1000; i++)
    {
        G[i]= malloc(sizeof(struct node));
        G[i]->data = i;
        G[i]->next = NULL;
    }

    fp = fopen("idk2.txt", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    while ((read = getline(&line, &len, fp)) != -1) {
        int vertexGettingConntected = line[0];
        struct node* newItem;
        printf("Retrieved line of length %zu :", read);
        int i = 0;
        while(line[i] != '\0'){
          if ( line[i] == ' '){
            i++;
          }
          else if (i == 0){
            newItem = malloc(sizeof(struct node));
            int itemStorage = line[0] - '0';
            newItem->next = NULL;
            newItem->data = itemStorage;
            G[itemStorage] = newItem;
            printf("This is first Number:%d\n", itemStorage);
          }
          else if (line[i] != ' '){
            struct node* addingItem = newItem;
            while(addingItem->next != NULL){
              addingItem = addingItem->next;
            }
            int itemStorage = line[i] - '0';
            struct node* newConnection = malloc(sizeof(struct node));
            addingItem->next = newConnection;
            newConnection->data = itemStorage;
            newConnection->next = NULL;
            printf("This is character:%c\n", line[i]);
            printf("This is connection:%i\n", itemStorage);
          }
          i++;
        }
    }

    fclose(fp);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);
    for(int printer = 1; printer<20; printer++){
        printf("%d\n",G[printer]->data);
    }
  }

EDIT: Просто хотел включить файл, который я читаю из:

1 3 4
2 4
3 1 4
4 2 1 3

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Я не уверен, почему вы хотите иметь массив указателей на node, для которого вы все выделяете память в начале вашей программы, не зная, сколько потребуется node s. Затем вы снова выделяете память при чтении из файла.

Учитывая ограничения на то, что нельзя использовать функции, вот как я прочитал файл и составил список:

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

typedef struct node_tag {
    int value;
    struct node_tag *next;
} node_t;

int main(void)
{
    char const *filename = "test.txt";
    FILE *input_file = fopen(filename, "r");
    if (!input_file) {
        fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
        return EXIT_FAILURE;
    }

    // read from file and build a list:
    node_t *head = NULL;
    node_t *tail = NULL;
    int value;
    int result = EXIT_SUCCESS;

    while (fscanf(input_file, "%d", &value) == 1) {
        node_t *new_node = calloc(1, sizeof *new_node);
        if (!new_node) {
            fputs("Not enough memory :(\n\n", stderr);
            result = EXIT_FAILURE;
            goto glean_up;
        }

        new_node->value = value;

        if (!head) {  // there is no head yet so new_node becomes the head
            head = tail = new_node;  // which is also the lists tail
            continue;
        }

        tail->next = new_node;
        tail = new_node;
    }

    // print the list:
    for (node_t *current_node = head; current_node; current_node = current_node->next)
        printf("%d ", current_node->value);
    putchar('\n');


clean_up:
    fclose(input_file);

    for (node_t *current_node = head, *temp; current_node; current_node = temp) {
        temp = current_node->next;
        free(current_node);
    }

    return result;
}

В идеале вы должны написать функции для управления списком:

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

typedef struct node_tag {
    int value;
    struct node_tag *next;
} node_t;

typedef struct list_tag {
    node_t *head;
    node_t *tail;
} list_t;

void list_create(list_t *list)
{
    list->head = list->tail = NULL;
}

bool list_push_back(list_t *list, int value)
{
    node_t *new_node = calloc(1, sizeof *new_node);
    if (!new_node)
        return false;

    new_node->value = value;

    if (!list->head) {
        list->head = list->tail = new_node;
        return true;
    }

    list->tail->next = new_node;
    list->tail = new_node;
    return true;
}

void list_print(list_t *list)
{
    for (node_t *current_node = list->head; current_node; current_node = current_node->next)
        printf("%d ", current_node->value);
}

void list_free(list_t *list)
{
    for (node_t *current_node = list->head, *temp; current_node; current_node = temp) {
        temp = current_node->next;
        free(current_node);
    }
}

bool read_int(FILE *input_file, int *value)
{
    return fscanf(input_file, "%d", value) == 1;
}

int main(void)
{
    char const *filename = "test.txt";
    FILE *input_file = fopen(filename, "r");
    if (!input_file) {
        fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
        return EXIT_FAILURE;
    }

    // read from file and build a list:
    list_t list;
    list_create(&list);
    int value;

    while (read_int(input_file, &value)) {
        if (!list_push_back(&list, value)) {
            fputs("Not enough memory :(\n\n", stderr);
            // clean up:
            fclose(input_file);
            list_free(&list);
            return EXIT_FAILURE;
        }
    }

    // print the list:
    list_print(&list);
    putchar('\n');

    // clean up:
    fclose(input_file);
    list_free(&list);
}

Выход:

1 3 4 2 4 3 1 4 4 2 1 3
0 голосов
/ 14 ноября 2018

Когда вы нажимаете пробел, вы повторяете i. В конце цикла вы повторяете i.

Поэтому, когда вы нажимаете пробел, вы дважды повторяете i, пропуская число и приземляясь на следующий пробел.

Вот почему вы получаете первый номер, а остальные пропускаете.

edit: удалены комментарии getline () из-за отзывов от @swordfish. Текущая реализация не вызывает проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...