从输入中获取数字的最佳方法?

时间:2016-02-03 08:20:04

标签: c

我想从包含文本和数字的输入文件中逐个字符循环。我以为我可以循环......

   char count;

    while( c != ' ' && c != '\n' && c != '\t' ) {
        count += c;
        c = fgetc(fp);
    }

说得到" 11"从文本文件然后使用atoi转换为int但我意识到我只是添加ASCII数字。我对C很新,从我理解的字符串只是char数组 - 这是否意味着我必须把" 1"和" 1"进入char数组?但是我不得不担心数组大小并将其转换为数字?

2 个答案:

答案 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跳过空格。如果找到一个数字就会成功,如果找到别的话就会失败。