Самая большая проблема, с которой вы сталкиваетесь, заключается в том, что вы не контролируете свой цикл чтения с возвратом самого чтения. Например, в вашем случае вы хотели бы:
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);
}
Приведенный выше код делает то же самое, что я предложил для обработки цикла чтения при успешном чтении пары значений из файла. Единственное отличие состоит в том, что он координирует значения 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) анализ необходимой информации из линии. Если у вас есть неправильная строка, это предотвращает влияние сбоя сопоставления на чтение оставшихся строк во входном файле.
Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы.
person
David C. Rankin
schedule
27.01.2020
struct mydata { int val; int wt; };
Затем вы можете просто создать свой массивstrct mydata arr[20] = {{ .val = 0; }};
Теперь вы можете координировать каждыйval
иwt
как один объект, например.arr[0].val
иarr[0].wt;
и т. д.. Читайте построчно с помощьюsize_t n = 0; while (fscanf(myfile, "%d %d", &arr[n].val, &arr[n].wt) == 2) { n++; }
Теперь у вас есть заполненный массив структуры и количество элементовn
. - person David C. Rankin   schedule 27.01.2020myFile=fopen("data.txt", "r");
всегда проверяйте (!=NULL) возвращаемое значение, чтобы убедиться, что операция прошла успешно. - person user3629249   schedule 28.01.2020for(i=0;i<sizeof(val);i++){
будет писать за конец массиваval[]
, потому чтоsizeof
возвращает количество байтов, а не количество целых чисел. Предложить:for(i=0;i<(sizeof(val) / sizeof( val[0] );i++){
- person user3629249   schedule 28.01.2020while(!feof(myFile)){ fscanf(myFile, "%1d%1d", &val[i], &wt[i]); }
Это не инициализирует и не увеличиваетi
, поэтому будет использоваться любое случайное значение в стеке, где находитсяi
- person user3629249   schedule 28.01.2020while()
использовать возвращаемое значение изfscanf()
в качестве управляющего значения, а неfeof()
- person user3629249   schedule 28.01.2020