我知道这是一个非常微不足道的问题但我需要快速帮助。我一直试图解决这个问题。我想要做的只是从具有
形式的文本文件中读取整数 8 blah blah
10 blah blah
2 blah blah
3 blah blah
我最终只想获取数字,将它们存储在数组中并将这些数字放入BST中。当我的文件只有数字时,我的BST工作正常,但没有指定的文件格式。
blah
是什么并不重要我只想获取数字并将它们存储在数组中。如果我拿出blah's
,我就可以这样做。使用fscanf
,我得到了我的代码来存储第一个数字8
,但它停在那里。此示例中还有四行,但文件中有多少行并不重要。它可能是12或6.我怎样才能正确地做到这一点。以下是我解决这个问题的不良尝试。
fscanf(instructionFile, "%d", &num);
我也尝试过像
这样的事情 while(!feof(instructionFile)){
fscanf("%d %s %s", &num, string1, string2);
}
要存储所有内容并且只使用整数,但是当我做这样的事情时,我的BST不起作用。
答案 0 :(得分:1)
使用fgets()
获取输入行,使用sscanf()
获取整数。在您使用fscanf()
的示例中,第一个调用将读取int
,并且下一个调用将失败,因为输入流中的下一个项目不是int
。每次失败后,错误输入都会保留在输入流中。通过一次获取一行,您可以在闲暇时扫描该行,然后再获取另一行输入。
以下是如何执行此操作的示例。请注意,您不应使用feof()
来控制读取循环;相反,使用fgets()
的返回值。此代码假定行上的第一个条目是您想要的数据,可能带有前导空格。可以针对稍微复杂的情况修改格式字符串。如果您需要更好地控制对行的解析,也可以使用strtok()
。
#include <stdio.h>
#include <stdlib.h>
#define MAX_LINES 100
int main(void)
{
FILE *fp = fopen("data.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Unable to open file\n");
exit(EXIT_FAILURE);
}
char buffer[1000];
int arr[MAX_LINES];
size_t line = 0;
while ((fgets(buffer, sizeof buffer, fp) != NULL)) {
if (sscanf(buffer, "%d", &arr[line]) != 1) {
fprintf(stderr, "Line formatting error\n");
exit(EXIT_FAILURE);
}
++line;
}
for (size_t i = 0; i < line; i++) {
printf("%5d\n", arr[i]);
}
fclose(fp);
return 0;
}
在调用sscanf()
之前添加空行检查会很好;现在,空行被认为是格式错误的数据。
示例文件的输出:
8
10
2
3
答案 1 :(得分:1)
如果你只想从一个文件的混乱中挑出整数,那么你实际上需要通过指针识别每个起始数字(或者开始-
符号为负数)来处理你读过的每一行。每个整数一次找到一个。您可以使用指针和sscanf
执行此操作,或者可以使用strtol
使用endptr
参数移动到任何成功转换后的下一个字符。如果您愿意,也可以使用面向字符的输入(例如getchar
或fgetc
)手动执行数字识别和转换。
鉴于您开始使用fgets
和sscanf
方法,以下内容将继续。无论您使用sscanf
还是strtol
,整个关键是将下一次读取的开始推进到找到的每个整数之后的字符,例如
#include <stdio.h>
#include <stdlib.h>
#define MAXC 256
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to hold MAXC chars at a time */
int nval = 0; /* total number of integers found */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) {
char *p = buf; /* pointer to line */
int val, /* int val parsed */
nchars = 0; /* number of chars read */
/* while chars remain in buf and a valid conversion to int takes place
* output the integer found and update p to point to the start of the
* next digit.
*/
while (*p) {
if (sscanf (p, "%d%n", &val, &nchars) == 1) {
printf (" %d", val);
if (++nval % 10 == 0) /* output 10 int per line */
putchar ('\n');
}
p += nchars; /* move p nchars forward in buf */
/* find next number in buf */
for (; *p; p++) {
if (*p >= '0' && *p <= '9') /* positive value */
break;
if (*p == '-' && *(p+1) >= '0' && *(p+1) <= '9') /* negative */
break;
}
}
}
printf ("\n %d integers found.\n", nval);
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
示例输入
以下两个输入文件说明仅从混合输入中选取整数。你的档案:
$ cat dat/blah.txt
8 blah blah
10 blah blah
2 blah blah
3 blah blah
一个非常混乱的文件
$ cat ../dat/10intmess.txt
8572,;a -2213,;--a 6434,;
a- 16330,;a
- The Quick
Brown%3034 Fox
12346Jumps Over
A
4855,;*;Lazy 16985/,;a
Dog.
11250
1495
示例使用/输出
在你的情况下:
$ ./bin/fgets_sscanf_int_any_ex < dat/blah.txt
8 10 2 3
4 integers found.
真正凌乱的文件:
$ ./bin/fgets_sscanf_int_any_ex <dat/10intmess.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
10 integers found.
仔细看看,如果您有任何问题,请告诉我。
答案 2 :(得分:1)
简单方式&#34;只读整数&#34;如果失败则使用fscanf(file_pointer, "%d", ...)
和fgetc()
int x;
int count;
while ((count = fscanf(file_pointer, "%d", &x)) != EOF) {
if (count == 1) {
// Use the `int` in some fashion (store them in an array)
printf("Success, an int was read %d\n", x);
} else {
fgetc(file_pointer); // Quietly consume 1 non-numeric character
}
}
我的代码存储了第一个数字,即8,但它会停在那里。
这是因为违规的非数字输入仍然存在于FILE流中。该文本需要以某种其他方式使用。再次调用fscanf(instructionFile, "%d", &num);
会导致同样的问题:fscanf()
失败,因为初始输入是非数字的。
注意:OP的代码缺少FILE指针
// fscanf(????, "%d %s %s", &num, string1, string2);