我想从包含文本和数字的输入文件中逐个字符循环。我以为我可以循环......
char count;
while( c != ' ' && c != '\n' && c != '\t' ) {
count += c;
c = fgetc(fp);
}
说得到" 11"从文本文件然后使用atoi转换为int但我意识到我只是添加ASCII数字。我对C很新,从我理解的字符串只是char数组 - 这是否意味着我必须把" 1"和" 1"进入char数组?但是我不得不担心数组大小并将其转换为数字?
答案 0 :(得分:4)
虽然它看起来像是一个自然的解决方案,但我通常建议不要在潜在格式错误的输入上使用fscanf()
。
该功能存在几个问题,其中包括:
ftell()
/ fseek()
除外),因为您不知道完全它停止解析输入的位置。fscanf()
扼住了atoi()
/ strtol()
没有"0xz" ...)的一些极端情况。所有这些都将fscanf()
降级为只读取格式良好的输入,即您自己的程序之前以已知格式编写的内容。
对于可能不处于预期格式的任何类型的输入,我建议一次读取一行(fgets()
),并在内存中解析< / strong>,例如strtol()
:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define LINE_BUFFER_SIZE 256;
// ...
char line[ LINE_BUFFER_SIZE ];
fgets( line, LINE_BUFFER_SIZE, fp );
char * scanptr;
errno = 0;
long number = strtol( line, &scanptr, 0 );
if ( scanptr == line )
{
// not a number...
}
scanptr
现在指向数字解析结束的位置。number
包含已解析的数字,如果行未以数字开头,则为0,并且LONG_MAX
为resp。 LONG_MIN
如果找到的号码超出long
范围(在这种情况下也是errno == ERANGE
)。我不知道您的确切要求,所以如果您没有找到数字或者如何处理文本,我就无法给出一个很好的例子。但是,由于你在内存中得到了一行(或者更长行的第一个LINE_BUFFER_SIZE
个字符......),你可以使用string functions的整个范围。 strpbrk( line, "0123456789" )
可用于扫描下一个数字,或strpbrk( line, "+-0123456789" )
如果您的输入中有+-
...
答案 1 :(得分:1)
大多数人会使用fscanf
:
int number, items_scanned;
items_scanned = fscanf(fp, "%d", &number);
if (items_scanned == 0) {
/* Scanning for a number failed */
printf("Scan failed!\n");
}
printf("Found number: %d\n", number);
fscanf
跳过空格。如果找到一个数字就会成功,如果找到别的话就会失败。