Попытка чтения в файле и сохранение первого ввода в массиве val и второго ввода в массиве wt (weight) - PullRequest
1 голос
/ 27 января 2020

Мне нужно прочитать в файле с именем «data.txt» и сохранить первый вход в качестве значения и второй соответствующий ввод в качестве веса. У меня проблемы с чтением и сохранением значений.

data.txt (example)

3 25
2 20
1 15
4 40
5 50

Вот с чего я начал:

FILE *myFile;
myFile=fopen("data.txt", "r");


int val[20]={0}; //initialize value array to zero
int wt[20]={0}; 
int W=80; //Set capacity to 80
int i;
int n;

while(!feof(myFile)){ 
  fscanf(myFile, "%1d%1d", &val[i], &wt[i]);
}

n = sizeof(val)/sizeof(val[0]);
printf("%d", knapSack(W, wt, val, n));//prints out the maximum value
fclose(myFile);
return 0;

Я отредактировал приведенный выше код для следующего :

FILE *myFile;
myFile=fopen("data.txt", "r");


int val[20]={0};
int wt[20]={0};
int W=80; //Set capacity to 80
int i;
int n;

for(i=0;i<sizeof(val);i++){
  fscanf(myFile, "%1d%1d", &wt[i],&val[i]);
}

n = sizeof(val)/sizeof(val[0]);
printf("%d", knapSack(W, wt, val, n));//prints out the maximum value
fclose(myFile);
return 0;

Он продолжает выводить 55, когда я использую входные данные из примера data.txt.

Ответы [ 2 ]

1 голос
/ 27 января 2020

Самая большая проблема, с которой вы столкнулись, заключается в том, что вы не контролируете чтение-l oop с возвратом самого чтения. Например, в вашем случае вы хотели бы:

int i = 0;
while (fscanf(myFile, "%1d%1d", &wt[i],&val[i]) == 2)
    i++;

В конце чтения i будет содержать количество элементов, считанных в ваши массивы.

( примечание: вы не можете правильно использовать любую функцию ввода, если вы не проверите возврат ... )

Вместо чтения значений в отдельные массивы всякий раз, когда вы координируете несколько значений как один объект (например, каждую пару val и wt), вы должны думать struct. Это позволяет вам координировать оба значения как один объект.

Простой пример в вашем случае может быть:

#include <stdio.h>

#define MAXVAL 20   /* if you need a constant, #define one (or more) */

typedef struct {    /* struct with int val, wt + typdef for conveninece */
    int val, wt;
} mydata;

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

    size_t n = 0;                           /* number of elements read */
    mydata arr[MAXVAL] = {{ .val = 0 }};    /* array of mydtata */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    /* read all pairs of values in file into array */
    while (fscanf (fp, "%d %d", &arr[n].val, &arr[n].wt) == 2)
        n++;

    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);

    for (size_t i = 0; i < n; i++)  /* output values */
        printf ("arr[%zu]  %2d  %2d\n", i, arr[i].val, arr[i].wt);
}

Выше, код делает то же самое, что я предлагал при подготовке чтения -l oop при успешном чтении пары значений из файла. Единственное отличие состоит в том, что координаты значений val и wt в структуре.

Пример использования / Вывод

С вашими данными в файле dat/val_wt.txt, вы получите следующий вывод:

$ ./bin/read_val_wt dat/val_wt.txt
arr[0]   3  25
arr[1]   2  20
arr[2]   1  15
arr[3]   4  40
arr[4]   5  50

Хотя выше мы читаем напрямую с помощью fscanf, вы можете сделать ваше чтение более устойчивым, сначала прочитав каждую строку в массив символов, а затем проанализировав требуемые значения из массива символов с sscanf. По сути, вы делаете то же самое, но с помощью fgets/sscanf вы можете сделать независимую проверку (1) чтения строки; и (2) анализ требуемой информации с линии. Если у вас есть неправильно сформированная строка, она предотвращает сопоставление-сбой от влияния на чтение оставшихся строк во входном файле.

Просмотрите все и дайте мне знать, если у вас есть дальнейшие вопросы.

0 голосов
/ 27 января 2020

Упс, здесь много маленьких проблем ...

Во-первых, даже если вы не связаны, вы постоянно не можете проверить результат функций ввода. Это может привести к скрытию проблем ...

Далее, правило - , когда вы не получаете то, что ожидаете, трассировка промежуточные значения .

Если бы вы получили эти строки:

// uncomment next block for debugging
printf("n=%d\n);
for (i = 0; i < n; i++) {
    printf("%d %d\n", wt[i], val[i]);
}

Вы бы видели

n = 20
3 2
5 2
2 0
1 1
5 4
4 0
5 5
0

, показывающий, что:

  • n было 20 (не уверен, ожидали ли вы it)
  • вы читали свои значения по одному di git за один раз вместо одного целочисленного значения (из-за форматов %1d)

Мой совет:

for (i = 0; i<sizeof(val); i++) {        // do not try to read more than array capacity
    if (2 != fscanf(myFile, "%d%d", &wt[i], &val[i])) break;  // stop when no more data
}

n = i;     // number of actual values

// uncomment next block for debugging
/*
printf("n=%d\n);
for (i = 0; i < n; i++) {
    printf("%d %d\n", wt[i], val[i]);
}
*/
...