我有一个文本文件,我正在尝试提取所有整数并将它们放入数组中。整数的大小各不相同,可能包括逗号和小数(如果存在小数,我会截断小数)。
这是文件中的文字:
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, 1, 1986]
?
原始代码使用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)
答案 0 :(得分:3)
这是一个很好的练习,你需要思考,但你必须一步一步地考虑它,并考虑到你一次阅读文件中所遇到的所有角色突发事件。
您可以采取的两种主要方法是(1)读取每个字符,如果是数字,则执行转换和中间和来构建整数的值,或者(可能更容易)(2)将每个数字添加到字符数组,当您到达非数字时, nul-terminate 并使用atoi
或{{1}将字符数组转换为整数}。我发现第二个更容易一些。 (否则,您需要处理遇到的每个数字的中间和)
采用第二种方法,您可以编写类似于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;
}
的数字进行十进制截断等。
您可以使用调用'.'
的短程序测试数据文件中的代码。 注意:代码作为第一个参数从文件中读取(如果默认情况下没有提供文件名,则来自findints
。)
stdin
示例输出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
enum { BASE = 10, MAXD = 21, MAXSZ = 128 };
int findints (FILE *fp, int *arr, size_t sz);
int main (int argc, char **argv) {
int a[MAXSZ] = {0}, i, n = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
n = findints (fp, a, MAXSZ); /* call findints */
printf ("\n the array has '%d' elements.\n\n", n);
for (i = 0; i < n; i++)
printf (" array[%2d] : %d\n", i, a[i]);
putchar ('\n');
if (fp != stdin)
fclose (fp);
return 0;
}
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
进程以执行您希望它执行的操作。原始数据文件中未解决的一个此类情况是,前导findints
后跟数字(例如'.'
(比如.nnn
))。由于您的原始问题会截断所有小数,因此上面应评估为.1234
,但0
是有效的整数值。因此,您可以决定将任何小数部分视为原始语句中0
0.1234
,但仍然可以将其自身添加到数组中。
因此,当您的字符数组中没有添加任何数字时,您需要对0
进行测试。遇到'.'
之前存在数字的情况已由'.'
涵盖,因此您只需添加以下内容:
if (idx && !isdigit(c))
这是构建您自己的解析例程的好处,您可以定制它以完成您需要它做的事情,并在遇到需要解决的其他案例时添加它。
如果您有任何问题,请与我们联系。
答案 1 :(得分:0)
fgets(strbuff, sizeof(strbuff), fp)
/
)。,
)并尾随/n
strtok()
atof()
atof()
结果存储为long long int
答案 2 :(得分:-1)
首先将行(从文件)复制到字符串中然后您可以使用"atoi(some_string)"
函数返回位于some_string
的第一个整数....我认为它可以帮助使数组成为你希望......