如何从文件中读取特定的字符和整数(更新问题)?
How to read specific chars and ints from file (update question)?
我有一个输入文件:
H
3(3,3)
V
1(5,4)
2(7,7)
我正在阅读这篇文章:
12 FILE *fp = fopen (argv[1], "r");
13 if (fp == NULL)
14 {
15 return EXIT_FAILURE;
16 }
17 Stack* top = NULL;
18 char gets[1024];
19 while (fgets (gets, 1024, fp))
20 {
21 char node;
22 int width = 0;
23 int height = 0;
24 int check = (sscanf (gets, " %c(%d,%d", &node, &width, &height));
25 if (check == 1)
26 {
27 push(&top,node,0,0);
28 }
29 else if (check == 3)
30 {
31 push(&top,node,width,height);
32 }
33 }
34 fclose (fp);
效果很好。
1 3(3,3)
2 1(5,4)
3 2(7,7)
4 V
5 H
但是当我读到类似这样的内容时(由于文件很大,输入被缩短了):
1 93(11,16)
2 11(12,33)
3 H
4 34(7,11)
5 10(9,27)
6 V
7 32(12,30)
8 30(12,16)
9 41(12,19)
10 H
11 V
12 50(12,13)
我明白了,例如:
1 9(0,0)
2 1(0,0)
3 H
4 3(0,0)
5 1(0,0)
6 V
7 3(0,0)
8 3(0,0)
9 4(0,0)
10 H
11 V
12 5(0,0)
如何修复此错误以提供正确的输出 - 因此我获得了节点的正确值而不是 9 而不是例如 93。
编辑:
它不工作,我得到这样的东西:
20 45(11,16)
21 45(11,16)
22 45(11,16)
23 45(11,16)
24 45(11,16)
25 45(11,16)
26 45(11,16)
27 45(11,16)
28 45(11,16)
29 45(11,16)
30 45(11,16)
31 45(11,16)
32 45(11,16)
33 45(11,16)
34 45(11,16)
35 45(11,16)
36 45(11,16)
37 45(11,16)
38 45(11,16)
39 45(11,16)
40 45(11,16)
41 45(11,16)
42 45(11,16)
43 45(11,16)
44 45(11,16)
45 45(11,16)
46 45(11,16)
47 45(11,16)
这甚至不是输入。
将 int check = (sscanf (gets, " %c(%d,%d", &node, &width, &height));
和 char node;
替换为更复杂的行:
int node = 0;
int check = (sscanf (gets, "%d(%d,%d", &node, &width, &height));
if (check == 0)
{
char n = 0;
check = sscanf(gets, " %c", &n);
node = n;
}
在你的问题的这次迭代中,改变的是在第一个 "("
之前只有一个字符或单独一行,你现在可以有多个字符。您仍然希望能够读取 'H'
或 93
作为该行的第一部分,因此您需要调整 format-string 以读取多个第一个 "("
之前的字符,如果它是字母字符,则将其视为字符串,如果它由数字组成,则将其转换为整数值。您可以使用类似的东西:
#define MAXN 32
...
while (fgets (buf, MAXC, fp)) {
char tmp[MAXN];
int node, width, height;
switch (sscanf (buf, " %31[^(\n](%d,%d", tmp, &width, &height)) {
...
格式字符串是 " %31[^(\n](%d,%d"
其中 '\n'
包含在 否定 字符 class 中连同 '('
到trim 那些只包含单个字符的行中的 '\n'
。 [^..]
开头的 circumflex(例如 '^'
)告诉您阅读不包括字符 class 中包含的内容的字符。 (例如,遇到第一个否定字符时停止阅读)
一个完整的例子是:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXN 32
int main (int argc, char **argv) {
char buf[MAXC];
/* 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)) {
char tmp[MAXN];
int node, width, height;
switch (sscanf (buf, " %31[^(\n](%d,%d", tmp, &width, &height)) {
case 1 : printf ("single char/digit: '%s'\n", tmp);
break;
case 3 : if (sscanf (tmp, "%d", &node) == 1)
printf ("all values: %d %d %d\n", node, width, height);
else
fputs ("error: parsing node from tmp.\n", stderr);
break;
default : fputs ("invalid line format\n", stderr);
}
}
if (fp != stdin) /* close file if not stdin */
fclose (fp);
}
您可以将 switch()
语句更改为您的 if/else
语句。
例子Use/Output
根据您更新后的输入,您现在将获得:
$ ./bin/fgets_sscanf_multival2 dat/multivals2.txt
all values: 93 11 16
all values: 11 12 33
single char/digit: 'H'
all values: 34 7 11
all values: 10 9 27
single char/digit: 'V'
all values: 32 12 30
all values: 30 12 16
all values: 41 12 19
single char/digit: 'H'
single char/digit: 'V'
all values: 50 12 13
您可以在其中将所有价值推送到需要的堆栈中。如果您还有其他问题,请告诉我。
我有一个输入文件:
H
3(3,3)
V
1(5,4)
2(7,7)
我正在阅读这篇文章:
12 FILE *fp = fopen (argv[1], "r");
13 if (fp == NULL)
14 {
15 return EXIT_FAILURE;
16 }
17 Stack* top = NULL;
18 char gets[1024];
19 while (fgets (gets, 1024, fp))
20 {
21 char node;
22 int width = 0;
23 int height = 0;
24 int check = (sscanf (gets, " %c(%d,%d", &node, &width, &height));
25 if (check == 1)
26 {
27 push(&top,node,0,0);
28 }
29 else if (check == 3)
30 {
31 push(&top,node,width,height);
32 }
33 }
34 fclose (fp);
效果很好。
1 3(3,3)
2 1(5,4)
3 2(7,7)
4 V
5 H
但是当我读到类似这样的内容时(由于文件很大,输入被缩短了):
1 93(11,16)
2 11(12,33)
3 H
4 34(7,11)
5 10(9,27)
6 V
7 32(12,30)
8 30(12,16)
9 41(12,19)
10 H
11 V
12 50(12,13)
我明白了,例如:
1 9(0,0)
2 1(0,0)
3 H
4 3(0,0)
5 1(0,0)
6 V
7 3(0,0)
8 3(0,0)
9 4(0,0)
10 H
11 V
12 5(0,0)
如何修复此错误以提供正确的输出 - 因此我获得了节点的正确值而不是 9 而不是例如 93。 编辑: 它不工作,我得到这样的东西:
20 45(11,16)
21 45(11,16)
22 45(11,16)
23 45(11,16)
24 45(11,16)
25 45(11,16)
26 45(11,16)
27 45(11,16)
28 45(11,16)
29 45(11,16)
30 45(11,16)
31 45(11,16)
32 45(11,16)
33 45(11,16)
34 45(11,16)
35 45(11,16)
36 45(11,16)
37 45(11,16)
38 45(11,16)
39 45(11,16)
40 45(11,16)
41 45(11,16)
42 45(11,16)
43 45(11,16)
44 45(11,16)
45 45(11,16)
46 45(11,16)
47 45(11,16)
这甚至不是输入。
将 int check = (sscanf (gets, " %c(%d,%d", &node, &width, &height));
和 char node;
替换为更复杂的行:
int node = 0;
int check = (sscanf (gets, "%d(%d,%d", &node, &width, &height));
if (check == 0)
{
char n = 0;
check = sscanf(gets, " %c", &n);
node = n;
}
在你的问题的这次迭代中,改变的是在第一个 "("
之前只有一个字符或单独一行,你现在可以有多个字符。您仍然希望能够读取 'H'
或 93
作为该行的第一部分,因此您需要调整 format-string 以读取多个第一个 "("
之前的字符,如果它是字母字符,则将其视为字符串,如果它由数字组成,则将其转换为整数值。您可以使用类似的东西:
#define MAXN 32
...
while (fgets (buf, MAXC, fp)) {
char tmp[MAXN];
int node, width, height;
switch (sscanf (buf, " %31[^(\n](%d,%d", tmp, &width, &height)) {
...
格式字符串是 " %31[^(\n](%d,%d"
其中 '\n'
包含在 否定 字符 class 中连同 '('
到trim 那些只包含单个字符的行中的 '\n'
。 [^..]
开头的 circumflex(例如 '^'
)告诉您阅读不包括字符 class 中包含的内容的字符。 (例如,遇到第一个否定字符时停止阅读)
一个完整的例子是:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXN 32
int main (int argc, char **argv) {
char buf[MAXC];
/* 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)) {
char tmp[MAXN];
int node, width, height;
switch (sscanf (buf, " %31[^(\n](%d,%d", tmp, &width, &height)) {
case 1 : printf ("single char/digit: '%s'\n", tmp);
break;
case 3 : if (sscanf (tmp, "%d", &node) == 1)
printf ("all values: %d %d %d\n", node, width, height);
else
fputs ("error: parsing node from tmp.\n", stderr);
break;
default : fputs ("invalid line format\n", stderr);
}
}
if (fp != stdin) /* close file if not stdin */
fclose (fp);
}
您可以将 switch()
语句更改为您的 if/else
语句。
例子Use/Output
根据您更新后的输入,您现在将获得:
$ ./bin/fgets_sscanf_multival2 dat/multivals2.txt
all values: 93 11 16
all values: 11 12 33
single char/digit: 'H'
all values: 34 7 11
all values: 10 9 27
single char/digit: 'V'
all values: 32 12 30
all values: 30 12 16
all values: 41 12 19
single char/digit: 'H'
single char/digit: 'V'
all values: 50 12 13
您可以在其中将所有价值推送到需要的堆栈中。如果您还有其他问题,请告诉我。