[英]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
讀取。 這樣,每次讀取都會消耗一行輸入,您不必擔心根據所使用的轉換說明符輸入流中剩余的內容。
此外,為了將多個值讀入A
和B
, A
和B
必須是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.