fscanf提取文件中不同大小的多个整数
我有一个文本文件,我试图提取所有整数,并将它们放入一个数组中。整数大小不一,可能包括逗号和小数(如果有小数,我会截断小数)。fscanf提取文件中不同大小的多个整数,c,C,我有一个文本文件,我试图提取所有整数,并将它们放入一个数组中。整数大小不一,可能包括逗号和小数(如果有小数,我会截断小数)。 以下是文件中的文本: This is a test text file... This is line 2. This could be line 3. Ben Franklin was here. Blah! Pi is 3.1415 The dinosaurs died 65,000,000 years ago. I am 31 years old. Our baby
以下是文件中的文本:
This is a test text file...
This is line 2.
This could be line 3.
Ben Franklin was here.
Blah!
Pi is 3.1415
The dinosaurs died 65,000,000 years ago.
I am 31 years old.
Our baby's due date is the 9th of April.
Tom's bday is 9/1/1986
我可以用任何方式制作一个数组,比如:
[2,3,3,65000000,31,9,9,11986]
原始代码使用了getc()
,但这不起作用,因为它一次只能抽出一个数字
int find_ints(FILE *fp, int arr[])
{
int ch, num = 0;
while((ch = getc(fp)) != EOF) {
if(isdigit(ch)) {
*arr++ = ch - '0';
num++;
}
}
return num;
}
使用fscanf是更好的方法吗
如果是这样的话,有人能带我看一下吗?起初我有这个,但它只抓住了第一个int
fscanf(fp, "%*[0123456789,]%d", arr)
首先将行(从文件)复制到字符串中,然后您可以使用“atoi(some_string)”
函数返回some_string
中的第一个整数……我认为这有助于按照您的期望制作数组……fgets(strbuff,sizeof(strbuff),fp)
- 将所有令牌(即
)替换为空格/
- 删除所有逗号(
)和尾部的,
/n
- 使用strtok()
- 使用
atof()解析每个令牌
- 将
结果存储为atof()
long-long-int
- 对每个令牌重复此操作
- 每行重复一次
atoi
或strtol
终止字符数组并将其转换为整数。我觉得第二个比较容易。(否则,您需要处理遇到的每个数字的中间和)
采用第二种方法,您可以编写类似以下内容的findints
:
int findints (FILE *fp, int *arr, size_t sz)
{
int c, n = 0, idx = 0;
char tmp[MAXD] = "";
while ((c = fgetc (fp)) != EOF) { /* for each char */
if (c == ',') /* get next if , */
continue;
if (idx && !isdigit(c)) { /* if end of digits */
tmp[idx] = 0; /* nul-terminate */
arr[n++] = (int) strtol (tmp, NULL, BASE); /* convert to int */
idx = 0; /* reset idx */
memset (tmp, 0, sizeof tmp); /* reset tmp */
if (n == (int)sz) { /* validate sz < MAXSZ */
fprintf (stderr, "warning: MAXSZ reached.\n");
break;
}
if (c == '.') /* truncate after '.' */
while (isdigit ((c = fgetc (fp)))) {}
}
if (isdigit (c)) /* add digit to char array */
tmp[idx++] = c;
}
return n;
}
示例输出
$ ./bin/txt2array <dat/getint.txt
the array has '9' elements.
array[ 0] : 2
array[ 1] : 3
array[ 2] : 3
array[ 3] : 65000000
array[ 4] : 31
array[ 5] : 9
array[ 6] : 9
array[ 7] : 1
array[ 8] : 1986
这就是构建您自己的解析例程的好处,您可以对其进行定制,使其完全满足您的需要,并在遇到需要解决的其他情况时添加到解析例程中
如果您有任何问题,请告诉我。它似乎有点松散。假设在
1e9
格式中有一个浮点数?假设有一个日期,格式为26.3.2016
?假设有短语可以是64,65项
。假设有一个负数?我建议一个字符一个字符地读,直到你遇到一个数字,然后你处理一个数字,直到你的规则完成为止。如何累积一个数字<代码>整数=0代码>然后对于每个数字数字=数字*10+ch-'0'代码>你所说的“各种大小的整数”是什么意思?使用fscanf是更好的方法吗?不可以。当您正在读取的行具有可能不同的内容时,使用fscanf
即使是更好的选择,也很少。您的选择是面向字符的输入(正如您使用fgetc
),在读取每个字符时对其作出反应;或者是面向行的输入(如fgets
或getline
),您一次读取一行,并使用sscanf
或沿着字符串向下移动指针来解析结果缓冲区<代码>fscanf
对于这样的问题,就像试图在方孔中塞进一个圆销钉一样。角落案例:.123
应该变成什么:0
?(这是一个包含小数点的数字)或123
Nice-response bTwnone无有效角盒。根据这个问题,截断'.
后面的所有内容将导致0
,但由于0
是一个有效的整数,因此可能会在数组中结束。接得好。非常感谢,大卫。我真的很感谢你的帮助!这并不解决
和,
所需的处理。如果“将所有令牌(即/
)替换为空格”,则转换将失败65000000
和9/1/1986
,并且无法截断3.1415
。您必须单独处理分隔符。@DavidCRankin
由atof处理并强制转换为int。,
需要删除,而不是替换为空格,日期分隔符替换为空格,其余由strtok()完成。已授予,您的。
由atof
处理,随后对int
的强制转换将截断小数部分。非常感谢您的输入。我真的很感激。
$ ./bin/txt2array <dat/getint.txt
the array has '9' elements.
array[ 0] : 2
array[ 1] : 3
array[ 2] : 3
array[ 3] : 65000000
array[ 4] : 31
array[ 5] : 9
array[ 6] : 9
array[ 7] : 1
array[ 8] : 1986
while ((c = fgetc (fp)) != EOF) { /* for each char */
...
if (idx && !isdigit(c)) { /* if end of digits */
...
}
/* consider '.nnn' as 0 */
if (c == '.' && isdigit ((c = fgetc (fp)))) {
while (isdigit ((c = fgetc (fp)))) {}
arr[n++] = 0;
}
...