在c中将文本文件读入字符数组

时间:2014-11-12 22:14:10

标签: c arrays csv char text-files

我正在编写一个程序,该程序使用命令行参数从用户接收文本文件的名称。文本文件是一个非常简单的CSV文件,例如:

Bob's experiment,12,14,15,16
Mary's experiment,16,15,18

我只是希望它打印实验名称,然后是所有数值的平均值。我试图通过将所有数字和逗号放入一个字符数组来尝试这样做,但我不知道我哪里出错了。

这就是我所拥有的:

int main(int argc, char *argv[])
  {
    if(argc == 2) {
            FILE *txt_file;
            txt_file=fopen(argv[1], "rt");
            char str[4096];

            if(!txt_file) {
                    printf("File does not exist.\n");
                    return 1;
            }

            while(!feof(txt_file)){
                    char s;
                    s = fgetc(txt_file);

                    //prints experiment name
                    if(s != ',' && (!isdigit(s))) {
                            printf("%c", s);
                    }

                    if(isdigit(s) || s == ',') {
                            fgets(str, 4096, txt_file);
                    }
               }
             fclose(txt_file);
             return 0;
         }

2 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点,但您应该根据您从文件中读取的数据类型定制输入例程。在这里,您正在阅读数据的,因此您应该专注于面向行的输入例程(fgetsgetline或一个鞋拔{{} 1}})。基本方法是从文件中读取一行输入到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

答案 1 :(得分:-1)

我认为这会做你想要的。

#include <stdio.h>

int main(int argc, char* argv[])
{
    int n = 0, count = 0, t = 0;
    if(argc == 2) {
            FILE *txt_file;
            txt_file=fopen(argv[1], "rt");
            char str[4096];

            if(!txt_file) {
                    printf("File does not exist.\n");
                    return 1;
            }

            while(!feof(txt_file)){
                    char s;

                    s = fgetc(txt_file);

                    //prints experiment name
                    if(s != ',' && (!isdigit(s))) {
                            if(n!=0) {
                              printf("%d\n", n / count);
                              n = 0;
                              count = 0;
                            }
                            printf("%c", s); 
                    }

                    if(s == ',') {
                            fscanf(txt_file, "%d", &t);
                            n+=t;
                            count++;
                    }
               }
             printf("%d\n", n / count);
             fclose(txt_file);
             return 0;
         }
}