从stdin(C)读取未知数量的整数
我需要读取一个输入文件,如:从stdin(C)读取未知数量的整数,c,stdin,integer,C,Stdin,Integer,我需要读取一个输入文件,如: 1 19 20 41 23 2 41 52 43 3 90 91 941 4 512 5 6 51 61 每一奇数行都是一个整数。每个偶数行都是未知数量的整数 这在C语言中很容易++ while( cin >> k ){ ............ } 我不太习惯C,所以我不能用C。有什么办法吗?通过以下方式运行输入文件: #include <stdio.h> int main() { int k; wh
1
19 20 41 23
2
41 52 43
3
90 91 941
4
512
5
6
51 61
每一奇数行都是一个整数。每个偶数行都是未知数量的整数
这在C语言中很容易++
while( cin >> k ){
............
}
我不太习惯C,所以我不能用C。有什么办法吗?通过以下方式运行输入文件:
#include <stdio.h>
int main() {
int k;
while (scanf("%d", &k) == 1) {
printf("read number: %d\n", k);
}
return 0;
}
#包括
int main(){
int k;
而(scanf(“%d”,&k)==1){
printf(“读取编号:%d\n”,k);
}
返回0;
}
结果:
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
阅读编号:1
阅读编号:19
阅读编号:20
阅读编号:41
阅读编号:23
阅读编号:2
阅读编号:41
阅读编号:52
阅读编号:43
阅读编号:3
阅读编号:90
阅读编号:91
阅读号码:941
阅读编号:4
阅读编号:512
阅读编号:5
阅读编号:6
阅读编号:51
阅读编号:61
这是您在原始问题中引用的代码的C模拟。请看一下getc(3)或scanf(3)我将其分解为两个操作:读取一行,然后读取该行中的整数。下面是一个使用标准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
}
}
我会做以下一件事:
- fgetc()读取单个字符并自己解析它们(累积数字,直到碰到空格,并且有一个整数要用atoi()转换;如果空格是换行符,则它会终止一个整数列表)
- fgets()一次读取一行,然后解析它返回的字符串(再次查找分隔值的空格)
- 我会在不同的任务中中断程序
第一步是能够读一对行,第一行告诉你要读的数字,然后第二行读实际数字。为此,一个名为
read\u set
的函数可能很有用。它应该能够返回读取的数字,并发出文件结束以及错误的信号。为此,我们可以定义如下数据结构:
struct numbers {
long *data; /* or choose a type depending upon your needs */
size_t len;
};
然后我们可以用原型声明我们的函数:
int read_set(FILE *fp, struct numbers *num);
该函数将为num->data
分配内存,并将num->len
设置为正确的值。它返回0表示成功,否则返回一组错误条件。我们以后可能会喜欢使用enum
作为返回状态。现在,假设0=成功,1=文件结束,其他一切都是错误
然后调用方在循环中调用read\u 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 */
}
对于实现read\u set()
:它必须读取两行。有很多,所以您可以使用其中的任何一个,先读取一行,然后读取一个数字(检查其返回值!)。一旦有了数字编号,n
,就可以读取内存中的下一行,并执行以下操作:
num->data = malloc(n * sizeof *num->data);
num->len = n;
然后,您可以反复调用sscanf()
或strtol()
将数字存储在num->data
中。您应该进行检查,以确保n
数字准确地位于该行
请注意,您也可以用其他方式编写
read_set()
:逐行读取一个字符,并在读取时解析数字。这样做的优点是只需对数据进行一次检查,并且不需要大的缓冲区来将整个输入行存储在内存中,但缺点是自己做低级工作,一个字符一个字符地读取数据可能会很慢。我提出了这样一个解决方案:
#包括
内部主(空)
{
int指数=0;
char ch;
int-arr[1024];
而(scanf(“%d%c”、&arr[index++]、&ch)!=EOF)
{
如果(ch='\n')
{
//一行被读入arr
//此行中的整数数=索引
//可以处理arr[]的其余代码
//范例
int i;
对于(i=0;i
您需要注意行吗,还是这只是一系列的整数?在你的例子中,看起来奇数行是序列号,偶数行代表其他东西。david我需要注意这些行。这就是我不能做这件事的原因。我需要停止在每个偶数行的末尾获取新值。因为我有一个带有属性id和list的结构。每一奇数行是一个id,每一偶数行是一个列表。我想用两行数据填充一个结构,然后移动到另一个结构,用另外两行数据填充它,等等…一次读取一整行数据,然后将其作为字符串解析,非常感谢。我现在就试试。但是如果我不能假定一个固定的最大行长呢?如果输入流包含超过1024-2个字符并且fgets()
以数字文字分割输入流呢?您将得到两个数值,而不是一个。例如,从12345开始,在下一次调用fgets()
之后,可以在For循环的最后一次迭代中得到123,在For循环的第一次迭代中得到45。因此,对于这项任务,我更喜欢scanf()
和fscanf()
,如肖恩所示。@RobinKlose:Sean发布的scanf()
解决方案不能解决问题,因为它不能区分换行符和其他空格。@DietrichEpp:好的,我明白你的意思。发问者需要跟踪这些线。但是,您是否看到了一种解决上述问题的简单方法?请注意,getline()
是POSIX标准的一部分,它只是在Windows上不可用。我可以正确地读取该行,但scanf循环会无限地为我打印第一个数字。