读取文件,然后将其分类为10列

时间:2019-01-21 18:42:27

标签: c

我正在寻找一个txt文件,其中每行10列包含1199个数字,我知道最后一行将有10列或更少的列。 但是,第一行有11列。

感谢您的帮助。

#include <stdio.h>

#define t 1024

int main()
{
    int i=0, c;
    char p[t];
    FILE *f;
    f = fopen("CMB.txt", "r");
    while ((c = getc(f)) != EOF)
    {
        fscanf(f, "%s", p);
        if(i%10 == 0 && i > 0)
        {
            printf("\n");
        }
        printf("%s ", p);
        if (c == '\n')
        {
            i++;
        }
    }
    printf("\n %d", i+1);
    fclose(f);
}

4 个答案:

答案 0 :(得分:0)

当我尝试您的代码时,它可以正确打印您期望的10列,也许您在修改后没有重新编译。 这是您的代码,我只删除了文件的读取和打印字符。

#include <stdio.h>

int main()
    {
        int i=0;
        //, c;
       // char p[t];
       // FILE *f;
       // f = fopen("CMB.txt", "r");
        while (i<30)
        {
          //  fscanf(f, "%s", p);
            if(i%10 == 0 && i > 0)
            {
                printf("\n");
            }
            printf("%d ", i);
           // if (c == '\n')
           // {
                i++;
           // }
        }
        // printf("\n %d", i+1);
       // fclose(f);
    }

答案 1 :(得分:0)

为什么您要在第一个数字前读一个字符?如果此字符是换行符,为什么只增加i

如果文件仅包含数字,则可以通过以下方式简化代码:

#include <stdio.h>

int main() {
    int i, n;
    FILE *f = fopen("CMB.txt", "r");
    if (f != NULL) {
        for (i = 0; fscanf(f, "%d", &n) == 1; i++) {
            /* output the number followed by a tab, or by a newline every 10 numbers */
            printf("%d%c", n, "\t\n"[i % 10 == 9]);
        }
        if (i % 10 != 0) {
            printf("\n");
        }
        fclose(f);
    }
    return 0;
}

答案 2 :(得分:0)

继续我先前的评论,从文本文件读取数据列时,通常最好使用面向行的输入功能,例如{{ 1}}或POSIX fgets,然后从充满getline的缓冲区中解析数据(或在缓冲区中向下移动指针以找出所需的内容)

在您处理固定数量的列(10)时,可能显示少于所有值的情况,sscanf提供了一种方法来精确确定每一行中存在多少个值,同时允许您如果少于10个,则使用数据。

sscanf(与所有sscanf函数一样)返回根据您提供的 format字符串进行的成功转换的次数(如果返回,则返回scanf在转换发生之前遇到输入的结尾)。如果要将每行数据的10个整数值读入整数数组名EOF,则可以使用arr将行读入缓冲区(例如fgets),然后用buf分隔buf中的整数值head,例如

sscanf

然后,您只需使用所需的任何 ... while (fgets (buf, MAXC, fp)) { /* read each line into buf */ /* parse into integer values with sscanf saving return */ int rtn = sscanf (buf, "%d %d %d %d %d %d %d %d %d %d", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4], &arr[5], &arr[6], &arr[7], &arr[8], &arr[9]); ... rtn语句来验证返回(if..else)。在此示例中,我们可以简单地对读取的值的数量求和,并为该示例的目的输出包含少于switch...个值数量的任何行的行号,例如

COL

完全将其放入,您可以执行以下操作:

        ...
        if (rtn > 0)    /* did at least one conversion take place? */
            n += rtn;   /* increment count of values read */

        if (rtn < COL)  /* were less than COL values read? */
            printf ("row[%zu]: %d values read.\n", row + 1, rtn);

        row++;  /* increment row count */
    }

示例输入文件

如您在问题中所述,读取每行10个整数的数据文件以读取119行,并读取9个整数的最后一行,您可以使用如下输入文件:

#include <stdio.h>

#define COL    10
#define MAXC 1024

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

    char buf[MAXC];
    int arr[COL] = {0};
    size_t n = 0, row = 0;
    /* 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;
    }

    while (fgets (buf, MAXC, fp)) { /* read each line into buf */
        /* parse into integer values with sscanf saving return */
        int rtn = sscanf (buf, "%d %d %d %d %d %d %d %d %d %d",
                        &arr[0], &arr[1], &arr[2], &arr[3], &arr[4],
                        &arr[5], &arr[6], &arr[7], &arr[8], &arr[9]);
        if (rtn > 0)    /* did at least one conversion take place? */
            n += rtn;   /* increment count of values read */

        if (rtn < COL)  /* were less than COL values read? */
            printf ("row[%zu]: %d values read.\n", row + 1, rtn);

        row++;  /* increment row count */
    }
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    printf ("%zu values read from file.\n", n);
}

使用/输出示例

对上述文件运行代码将产生预期的结果,即读取1199个值,每行10个整数,从最后一行读取9个整数,并注意短行:

$ head -n4 dat/1199_10col.txt; echo "<snip>"; tail -n4 dat/1199_10col.txt
    1    2    3    4    5    6    7    8    9   10
   11   12   13   14   15   16   17   18   19   20
   21   22   23   24   25   26   27   28   29   30
   31   32   33   34   35   36   37   38   39   40
<snip>
 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
 1191 1192 1193 1194 1195 1196 1197 1198 1199

虽然有很多方法可以做到这一点,并且可以说将$ ./bin/read10col <dat/1199_10col.txt row[120]: 9 values read. 1199 values read from file. fgets结合使用可以为更细粒度的错误检测提供机会,但这可能是更简单直接的方法之一。

仔细检查一下,如果还有其他问题,请告诉我。

答案 3 :(得分:0)

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

int main()
{
  FILE * fp;
  char *line;
  int i;
  size_t len = 0;
  fp = fopen("CMB.txt", "r");

  while (getline(&line, &len, fp) != -1)
  {
    fscanf(fp, "%s", line);
    if(i%10 == 0 && i > 0)
    {
      printf("\n");
    }
    printf("%s\t ", line);
    i++;
  }
  printf("\n\n%d", i);
  fclose(fp);
  return 0;
}

因此,现在文件中的数字按10列排序,但最后一行只有9列时应有9列。当我数数(i)以查看while循环读取多少行时,它只能读取1198,但我应该读1199。所以我猜测它正在跳过第一行?感谢帮助:D