簡體   English   中英

讀取文件,然后將其分類為10列

[英]Reading a file and then sorting it into 10 columns

我正在尋找一個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);
}

當我嘗試您的代碼時,它可以正確打印出您期望的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);
    }

您為什么在第一個數字之前讀一個字符? 如果此字符是換行符,為什么只增加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;
}

繼續我先前的評論,當從文本文件中讀取數據列時,通常最好一次使用面向行的輸入功能(例如fgets或POSIX getline讀取一行輸入,然后再從中解析數據。充滿sscanf緩沖區(或沿着緩沖區向下移動指針以選擇所需的內容)

在您處理固定數量的列(10)時,可能存在少於所有值的情況, sscanf提供了一種方法來精確確定每行中存在多少個值,同時允許您使用小sscanf值的數據存在10。

sscanf (與所有scanf函數一樣)將根據您提供的格式字符串返回成功進行轉換的次數(如果在轉換發生之前遇到輸入結束,則返回EOF )。 如果要將每行數據中的10個整數值讀入一個名為arr的整數數組中,則可以使用fgets將行讀入一個緩沖區(例如buf ),然后使用sscanf buf中的整數值分開

    ...
    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..elseswitch...語句來驗證返回( rtn )。 在這里,我們可以簡單地將讀取的值的數量相加,並為該示例的目的輸出任何包含少於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 */
    }

綜上所述,您可以執行以下操作:

#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);
}

輸入文件示例

如您在問題中所述,讀取每行10字節的數據文件以讀取119行,並讀取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

使用/輸出示例

對上面的文件運行代碼將產生預期的結果,即讀取1199個值,每行10個整數,從最后一行讀取9個整數,並注意短行:

$ ./bin/read10col <dat/1199_10col.txt
row[120]: 9 values read.
1199 values read from file.

盡管有許多方法可以做到這一點,並且可以說將fgetsstrtol結合strtol可以為更精細的錯誤檢測提供機會,但這可能是更簡單直接的方法之一。

仔細檢查一下,如果您還有其他問題,請告訴我。

#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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM