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

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

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

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

虽然它看起来像是自然的解决方案,但我通常建议不要在潜在的格式错误的输入上使用fscanf()

该function有几个问题,其中包括:

  • 无法从错误(缺少ftell() / fseek() )中优雅地恢复,因为您不知道它在何处停止解析输入。
  • 它导致使用未初始化值的难易程度(如果格式与输入不匹配,并且您没有正确检查返回代码)。
  • 一些极端情况,其中fscanf()在输入上窒息,其中atoi() / strtol()没有( “0xz” …)。

所有这些都将fscanf()降级为仅读取格式良好的输入,即您自己的程序之前以已知格式编写的内容。

对于可能不是预期格式的任何类型的输入, 我建议一次读取一行( fgets() ),并在内存中解析它 ,例如使用strtol()

 #include  #include  #include  #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字符……),你可以使用所有字符串函数 。 strpbrk( line, "0123456789" )可用于扫描下一个数字,或strpbrk( line, "+-0123456789" )如果你的输入可能有+-

大多数人会使用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跳过空白。 如果它找到一个数字就会成功,如果找到别的东西就会失败。