Как я должен заполнить массив целых из файла, используя аргументы командной строки? Размер файла и нет. элементов могут отличаться - PullRequest
2 голосов
/ 08 мая 2019

Я действительно новичок в программировании на C. У меня есть задание, в котором я должен заполнить массив целых чисел из текстового файла, используя аргументы командной строки. Массив должен иметь возможность принимать все числа из файла. Это сегмент кода, который должен выполнять вышеперечисленное, но он терпит неудачу. Я все еще должен добавить проверку ошибок, но мне просто нужно знать, где я иду не так, и если я нахожусь на правильном пути.

Из того, что я знаю до сих пор, мне придется использовать распределение памяти, чтобы сделать мой массив динамическим. Я использовал ftell (), чтобы найти размер файла в байтах, чтобы я мог соответственно выделить память.

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

int main(int argc, char *argv[]) {

    if (argc > 2) {
        printf(stderr, "Error, too many arguments supplied.");
        exit(1);
    }

    if (argc == 2) {
        int *numArray = NULL; //pointer to integer

        FILE* inputFile = fopen(argv[1], "r");

        fseek(inputFile, 0, SEEK_END);

        // calculating the size of the file 
        int fileSize = ftell(inputFile);

        numArray = malloc(fileSize * sizeof(int));

        if (numArray == NULL) {
            printf(stderr, "Error: File is empty.");
            exit(1);
        }

        int num;
        int arraySize = sizeof(numArray) / sizeof(numArray[0]);

        for (int i = 0; i < arraySize; i++) {
            fscanf(inputFile, "%d", &num);
            numArray[i] = num;
        }

        fclose(inputFile);
    }

}

Если файл содержит: 67, 66, 353, 789, 2342, NumArray = {67, 66, 353, 789, 2342}

1 Ответ

2 голосов
/ 08 мая 2019

В коде есть несколько проблем:

  • <fstream> - заголовок C ++, не смешивайте C и C ++.
  • printf(stderr, "Error, too many arguments supplied."); должен выдавать предупреждение онесоответствие типов в первом аргументе.используйте fprintf для печати в stderr.
  • Файл открыт в текстовом режиме, а не в двоичном, поэтому ftell() может не возвращать количество байтов в файле.
  • Ошибка открытия файла не проверена.
  • Выделение fileSize * sizeof(int) излишне.Числа представлены в текстовом формате, поэтому в файле можно найти не более fileSize / 2 чисел и, вероятно, намного меньше этого значения.
  • Ошибка выделения байтов не означает, что файл пуст.
  • Вы должны перераспределить массив, когда вы читаете больше чисел из файла.Это также позволяет считывать данные с устройств, которые нельзя найти, таких как терминалы и именованные каналы.
  • arraySize = sizeof(numArray) / sizeof(numArray[0]) не вычисляет количество элементов в массиве, поскольку numArray является указателем на массив, а немассив.Кроме того, вы должны просто сохранить число фактических чисел, которое является окончательным значением i в цикле for.
  • вы должны проверить возвращаемое значение fscanf(): 1 означает, что преобразование выполнено успешно, 0 означает наличие неверного ввода, которое не может быть преобразовано в целое число, EOF означает конец файла или, возможно, ошибку ввода-вывода.

Вот измененная версия:

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

int main(int argc, char *argv[]) {

    if (argc != 2) {
        fprintf(stderr, "The program expects a single command line argument\n");
        return 1;
    } else {
        int *numArray = NULL;
        size_t arraySize = 0;
        size_t arrayCount = 0;
        FILE *inputFile = fopen(argv[1], "r");
        int res, num;

        if (inputFile == NULL) {
            fprintf(stderr, "Cannot open file %s: %s\n", strerror(errno));
            return 1;
        }
        while ((res = fscanf(inputFile, "%d", &num)) == 1) {
            if (arrayCount >= ArraySize) {
                size_t newSize = arraySize ? arraySize * 2 : 32;
                int *newArray = realloc(numArray, newSize * sizeof(int));
                if (newArray == NULL) {
                    fprintf(stderr, "Out of memory for %zu elements\n", newSize);
                    exit(1);
                }
                numArray = newArray;
                arraySize = newSize;
            }
            numArray[arrayCount++] = num;
        }
        if (res != EOF) {
            fprintf(stderr, "Invalid input for element %zu\n", arrayCount);
        }
        if (arrayCount == 0) {
            if (res == EOF) {
                fprintf(stderr, "File %s is empty\n", argv[1]);
            }
            fclose(inputFile);
            return 1;
        }
        ...  // do something with the arrayCount elements in numArray
        free(numArray);
        fclose(inputFile);
    }
    return 0;
}
...