簡體   English   中英

如何讀取文本文件中的兩列數字?

[英]How can I read two columns of numbers in a text file?

我的 .txt 看起來像這樣,例如:

1.0 2.0

1.0 1.0

2.0 3.0

2.0 1.0

我想在需要時使用每一行來運行這個文件。 為了解釋,我有一個方程 (L = Ax + B),我需要為不同的 x 計算它。 有沒有辦法單獨讀取文件中的每一行,在該行取 A 和 B。 所以 L 的第一項將使用第一個 A 和 B。

我以前沒有這樣做過。 這是我已經知道的:

void coefficients(double *A, double *B) {
    FILE *infile;
    
    if(2!=fscanf(infile,"%lf %lf",A, B)) {
        printf("Error reading parameters from file\n");
        exit(1);
        
    }
    fclose(infile);
}

然后在 int_main 中調用它:

    double A;
    double B;
    // Read in from file; 
    coefficients(&A, &B);

您可以使用此方法通過使用fgets()逐行讀取文本文件 (file.txt) 到字符數組 ( buffer ),然后使用sscanf()解析它以在其中找到雙sscanf()值。

代碼

double a=0;
double b=0;

int bufferLength = 1024;
char buffer[bufferLength];

FILE *fp = fopen("file.txt", "r");
if (!fp){
    printf("Cant open file\n");
    return -1;
}

while(fgets(buffer, bufferLength, fp)) {
    //printf("%s\n", buffer);   
    if (2==sscanf(buffer, "%lf %lf", &a,&b)){
        printf("a: %f   b: %f\n", a,b);
    }
}

fclose(fp);

對於包含潛在空行和包含除您要查找的double值對之外的其他內容的潛在行的文件,最好將每一行讀入緩沖區並使用sscanf從緩沖區解析所需的值,而不是嘗試直接用fscanf讀取。 這樣,每次讀取都會消耗一行輸入,您不必擔心根據所使用的轉換說明符輸入流中剩余的內容。

此外,為了將多個值讀入ABAB必須是double精度數組(或可以容納多個double值的已分配內存塊)

例如在main()可以聲明:

#include <stdio.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */
...
int main (int argc, char **argv) {

    double a[MAXC] = {0}, b[MAXC] = {0};    /* arrays of MAXC doubles */

現在您有1024雙精度值的存儲空間。 讀取double值的coefficient函數應返回讀取的值數。 它還應該將打開和驗證的FILE*流作為參數。 (如果無法在調用者中驗證打開文件——沒有理由調用函數來嘗試讀取開始)

把它放在一起你可以這樣做:

size_t coefficients (FILE *fp, double *a, double *b)
{
    char buf[MAXC];         /* buffer for reading each line */ 
    size_t ncoeff = 0;      /* number of coefficient pairs read */

    while (ncoeff < MAXC && fgets (buf, MAXC, fp))  /* read each line */
        /* if it contains 2 double values */
        if (sscanf (buf, "%lf %lf", &a[ncoeff], &b[ncoeff]) == 2)
            ncoeff++;       /* increment counter */

    return ncoeff;          /* return total count of pairs read */
}

一個簡短的例子,你將有:

#include <stdio.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */

size_t coefficients (FILE *fp, double *a, double *b)
{
    char buf[MAXC];         /* buffer for reading each line */ 
    size_t ncoeff = 0;      /* number of coefficient pairs read */

    while (ncoeff < MAXC && fgets (buf, MAXC, fp))  /* read each line */
        /* if it contains 2 double values */
        if (sscanf (buf, "%lf %lf", &a[ncoeff], &b[ncoeff]) == 2)
            ncoeff++;       /* increment counter */

    return ncoeff;          /* return total count of pairs read */
}

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

    double a[MAXC] = {0}, b[MAXC] = {0};    /* arrays of MAXC doubles */
    size_t n = 0;                           /* count of doubles returned */
    /* 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;
    }

    if (!(n = coefficients (fp, a, b))) {   /* validate coeff pairs read */
        fputs ("error: no double values read from file.\n", stderr);
        return 1;
    }

    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);

    for (size_t i = 0; i < n; i++)  /* output coefficients */
        printf ("a[%zu] : %.1f   b[%zu] : %.1f\n", i, a[i], i, b[i]);
}

(您可以根據需要調整數組的大小)

示例輸入文件

$ cat dat/coeffpairs.txt
    A B

    1.0 2.0

    1.0 1.0

    2.0 3.0

    2.0 1.0

示例使用/輸出

$ ./bin/readcoeff dat/coeffpairs.txt
a[0] : 1.0   b[0] : 2.0
a[1] : 1.0   b[1] : 1.0
a[2] : 2.0   b[2] : 3.0
a[3] : 2.0   b[3] : 1.0

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

這取決於你想做什么。 如果你只想讀取數據而不關心當它不是兩列形式時會發生什么,你可以在循環中使用 fscanf 讀取它:

double  A, B;
while(fscanf(fp, "%ld%ld", &A, &B) == 2) {
    // do something with A and B

這將讀取文件中的任何數字序列 - 可能在兩列或全部在一行中,或者在帶有空行的行之間隨機拆分,並且當它到達任何不是數字的東西(或文件的末尾)時將停止, 並將忽略末尾的任何奇數單個數字)。

另一方面,如果您想驗證每行數字是兩個並且沒有空行,則可以使用 fgets+sscanf:

char line[256];    
while (fgets(line, sizeof line, fp)) {
    double A, B;
    int end;
    if (sscanf(line, "%ld%ld %n", &A, &B, &len) == 2 && line[end] == 0) {
        // got a line with (just) a pair of numbers
    } else {
        fprintf(stderr, "malformed input line: %s", line);
    }
}

如果您還想檢查數字是否按列排列,那就有點棘手了。 您可以很容易地檢查左對齊或右對齊的列

char line[256];
int a_col = -1, b_col = -1, lineno = 0;    
while (fgets(line, sizeof line, fp)) {
    double A, B;
    int a_right, b_right, end;
    ++lineno;
    if (sscanf(line, "%ld%n%ld%n %n", &A, &a_right, &B, &b_right, &len) == 2 && line[end] == 0) {
        // got a line with (just) a pair of numbers
        if (a_col >= 0 && (a_col != a_right || b_col != b_right)) {
            fprintf(stderr, "columns on line %d not lined up with previous line\n", lineno);
        }
        a_col = a_right;
        b_col = b_right;
    } else {
        fprintf(stderr, "malformed input on line %d", lineno);
    }
}

暫無
暫無

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

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