[英]reading unknown number of integers from stdin (C)
I need to read an input file like :我需要读取一个输入文件,如:
1
19 20 41 23
2
41 52 43
3
90 91 941
4
512
5
6
51 61
Each odd line is an integer.每个奇数行是一个整数。 Each even line is unknown number of integers.
每个偶数行都是未知数量的整数。
It is very easy in C++在 C++ 中很容易
while( cin >> k ){
............
}
I'm not so used to C, so I couldnt make it in C. Any ways to do it?我不太习惯 C,所以我不能用 C。有什么方法可以做到吗?
Running your input file through:通过以下方式运行您的输入文件:
#include <stdio.h>
int main() {
int k;
while (scanf("%d", &k) == 1) {
printf("read number: %d\n", k);
}
return 0;
}
Results in:结果是:
read number: 1 read number: 19 read number: 20 read number: 41 read number: 23 read number: 2 read number: 41 read number: 52 read number: 43 read number: 3 read number: 90 read number: 91 read number: 941 read number: 4 read number: 512 read number: 5 read number: 6 read number: 51 read number: 61
This is the C analog of the code you reference in your original question.这是您在原始问题中引用的代码的 C 模拟。
The way I would do it is to break it down into two operations: read a line, then read the integers in that line.我的做法是将其分解为两个操作:读取一行,然后读取该行中的整数。 Here is a lazy implementation using the standard C library:
这是使用标准 C 库的惰性实现:
char line[1024], *p, *e;
long v;
while (fgets(line, sizeof(line), stdin)) {
p = line;
for (p = line; ; p = e) {
v = strtol(p, &e, 10);
if (p == e)
break;
// process v here
}
}
I would break the program in different tasks.我会在不同的任务中破坏程序。
The first step is to be able to read a pair of lines, the first line which tells you the number of numbers to read, and then the second line to read the actual numbers.第一步是能够读取一对行,第一行告诉您要读取的数字数量,然后第二行读取实际数字。 For this, a function called something like
read_set
might be useful.为此,称为
read_set
类的read_set
可能很有用。 It should be able to return the numbers read, and signal end of file as well as errors.它应该能够返回读取的数字,并发出文件结束和错误的信号。 For this, we can define a data structure such as:
为此,我们可以定义一个数据结构,例如:
struct numbers {
long *data; /* or choose a type depending upon your needs */
size_t len;
};
and then we can declare our function with the prototype:然后我们可以用原型声明我们的函数:
int read_set(FILE *fp, struct numbers *num);
The function will allocate memory for num->data
, and set num->len
to the correct value.该函数将为
num->data
分配内存,并将num->len
设置为正确的值。 It returns 0 for success, and a set of error conditions otherwise.它返回 0 表示成功,否则返回一组错误条件。 We might get fancy and use an
enum
for return statuses later.稍后我们可能会喜欢并使用
enum
作为返回状态。 For now, let's say that 0 = success, 1 = end of file, and everything else is an error.现在,假设 0 = 成功,1 = 文件结束,其他一切都是错误。
The caller then calls read_set()
in a loop:然后调用者循环调用
read_set()
:
struct numbers numbers;
int status;
while ((status = read_set(fp, &numbers)) == 0) {
/* process numbers->data, and then free it */
}
if (status == 1) {
/* hit end of file, everything is OK */
} else {
/* handle error */
}
For implementing read_set()
: it has to read two lines.为了实现
read_set()
:它必须读取两行。 There are many implementations of reading a full line in C , so you can use any of them, and read a line first, then sscanf()
/ strtoul()
it for one number (check its return value!).在 C 中有许多读取整行的实现,因此您可以使用它们中的任何一个,然后先读取一行,然后使用
sscanf()
/ strtoul()
读取一个数字(检查其返回值!)。 Once you have the number of numbers, n
, you can read the next line in memory, and do:获得数字数量
n
,您可以读取内存中的下一行,然后执行以下操作:
num->data = malloc(n * sizeof *num->data);
num->len = n;
You can then repeatedly call sscanf()
or strtol()
to store numbers in num->data
.然后,您可以重复调用
sscanf()
或strtol()
将数字存储在num->data
。 You should put in checks to make sure exactly n
numbers are on that line.您应该进行检查以确保该行上正好有
n
数字。
Note that you can write read_set()
in other ways too: read a line character by character, and parse the numbers as you read them.请注意,您也可以通过其他方式编写
read_set()
:逐个字符读取一行,并在读取数字时解析它们。 This has the advantage of going over the data only once, and not needing a big buffer to store the whole input line in memory, but the disadvantage is doing low-level stuff yourself and reading data character-by-character may be slow.这样做的优点是只遍历一次数据,不需要大缓冲区来将整个输入行存储在内存中,但缺点是自己做低级的事情,逐个字符读取数据可能很慢。
I would do one of:我会做以下之一:
fgetc() to read individual characters and parse them yourself (accumulate digits until you hit whitespace and you have an integer to convert with atoi(); if the whitespace is a newline, then it terminates a list of integers) fgetc() 读取单个字符并自己解析它们(累积数字直到遇到空格并且您有一个整数可以用 atoi() 转换;如果空格是换行符,则它终止整数列表)
fgets() to read a line at a time, and then parse the string (again, look for whitespace separating the values) that it returns. fgets() 一次读取一行,然后解析它返回的字符串(再次查找分隔值的空格)。
I came up with a solution like this:我想出了一个这样的解决方案:
#include <stdio.h>
int main(void)
{
int index = 0;
char ch;
int arr[1024];
while(scanf("%d%c", &arr[index++], &ch)!=EOF)
{
if(ch=='\n')
{
// One line is read into arr
// number of integers in this line = index
// Rest of your code which can proces arr[]
// Example
int i;
for(i = 0; i < index; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
// Set the index back to 0 for the upcoming line
index = 0;
}
}
return 0;
}
看看 getc(3) 或 scanf(3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.