Есть несколько способов сделать это, но вы должны адаптировать свою входную рутину с типом данными, которые вы читаете из файла. Здесь вы читаете строк данных, поэтому вам следует сфокусироваться на ориентированных на линию процедуры ввода (fgets
, getline
, или обувная машина scanf
). Основной подход состоит в том, чтобы прочитать строку ввода из вашего файла в buffer
, а затем проанализировать строку по мере необходимости. Вы можете сделать это, динамически распределяя все необходимое хранилище, или вы можете определить максимальное значение, которое должно быть достаточно большим для обработки ваших данных.
Далее вам нужно будет разобрать buffer
чтения из файла, чтобы получить experiment name
и каждый из values
, связанных с тем, что average
может быть вычислен. Опять же, есть много способов сделать это, но strtol
предназначен для этой цели. Он принимает pointer
в строку для преобразования и возвращает endptr
следующему символу, который не является числом. Это позволяет вам считывать значения и устанавливать pointer = endptr+1
, что позволяет вам читать следующий номер.
Я собрал эти части в приведенном ниже примере. Он прокомментирован, чтобы помочь вам следовать. Оставьте комментарий, если у вас есть какие-либо дополнительные вопросы:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXEXPS 256
int main (int argc, char* argv[])
{
if (argc < 2) {
fprintf (stderr, "error: insufficient input. Usage %s <filename>\n", argv[0]);
return 1;
}
char *line = NULL; /* line read from file (getline allocates if NULL) */
size_t n = 0; /* number of characters to read (0 - no limit) */
ssize_t nchr = 0; /* number of characters actually read by getline */
char *p = NULL; /* pointer to use parsing values from line */
char *lnp = NULL; /* second pointer to use parsing values from line */
char *expname[MAXEXPS] = {0}; /* array of MAXEXPS pointers for experiment names */
int expavg[MAXEXPS] = {0}; /* array of MAXEXPS ints to hold averages */
int val = 0; /* val returned by each call to strtol */
int eidx = 0; /* experiment index */
int idx = 0; /* value index */
FILE *txt_file = fopen(argv[1], "r");
if (!txt_file) {
fprintf (stderr, "error: unable to open file '%s'\n", argv[1]);
return 1;
}
while ((nchr = getline (&line, &n, txt_file)) != -1) /* read each line in file */
{
p = strchr (line, ','); /* find first ',' */
*p = 0; /* set it to null (zero) */
expname[eidx] = strdup (line); /* copy exp name to array (strdup allocates) */
lnp = ++p; /* set lnp to next char */
int sum = 0; /* reset sum to 0 */
idx = 0; /* reset idx to 0 */
while ((val = (int)strtol (lnp, &p, 10)) != 0 && lnp != p) /* read next number */
{
sum += val; /* add val to sum */
lnp = ++p; /* set lnp to next char */
idx++; /* inc idx */
}
expavg[eidx++] = (idx > 0) ? sum/idx : 0; /* calc avg for experiment */
}
fclose (txt_file);
/* print the averages of experiments */
n = 0;
printf ("\n Experiment Avg\n");
printf (" -----------------------\n");
while (expname[n])
{
printf (" %-18s %d\n", expname[n], expavg[n]);
n++;
}
printf ("\n");
/* free all allocated memory */
n = 0;
if (line)
free (line);
while (expname[n])
free (expname[n++]);
return 0;
}
выход:
$ ./bin/csvavgfixed dat/csvavg.dat
Experiment Avg
-----------------------
Bob's experiment 14
Mary's experiment 16
память выделение/свободное Резюме:
==22148== HEAP SUMMARY:
==22148== in use at exit: 0 bytes in 0 blocks
==22148== total heap usage: 4 allocs, 4 frees, 723 bytes allocated
==22148==
==22148== All heap blocks were freed -- no leaks are possible
==22148==
==22148== For counts of detected and suppressed errors, rerun with: -v
==22148== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Что не работает? Каков ваш реальный вопрос? –
Возможно, функция функций strchr и atoi полезна. Используйте atoi, чтобы найти значение первого числа в str, а затем используйте цикл с strchr, чтобы найти следующую запятую. –
Возможный дубликат [вычисления среднего значения из файла CSV в C] (http://stackoverflow.com/questions/26877131/calculating-average-of-values-from-a-csv-file-in-c) – BLUEPIXY