0

我的功能有问题sscanf。更具体地说,我想从 txt 文件中读取一个浮点数(我只需要一个浮点数作为行),但sscanf不识别这些情况:

3.4t

或者

4.t6

或者

4.5 6.5

或者

(this is an empty line)

我使用这段代码:

 #define LUNRIGA 200     

 char riga[LUNRIGA+1];

 while (fgets(riga,LUNRIGA,f) != NULL) {
      r = sscanf(riga,"%f",&numeri[i]);
      if (r == 1) { /* riga valida */
         printf("OK");
      }else{
         printf("Error");
         return 1; 
      }    
 }
4

2 回答 2

1

sscanf对输入非常挑剔。strtod使用or会有更好的运气strtol- 他们可以读取一个值,即使它后面是垃圾。更改您的代码如下:

#define LUNRIGA 200     

char riga[LUNRIGA+1];
char* tempPtr;

while (fgets(riga,LUNRIGA,f) != NULL) {
  numeri[i] = strtof( riga, &tempPtr );
  if (tempPtr > riga) { /* riga valida */
     printf("OK");
  }
  else {
     printf("Error");
     return 1; 
  }    
}

请注意,您似乎没有i在循环中增加 - 您可能想看看这是否真的是您想要的,或者您是否想在每次获得有效数字时增加它(假设您不只是想要最后一个值,但所有这些值......)

作为 的行​​为的一个小演示strtod,我写了几行代码:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
  char* s1="123.45t";
  char* p1;
  char* s2 = "   notanumber";
  double d1, d2;
  d1 = strtod(s1, &p1);
  printf("the number is %.2lf; the pointer is now %p; string is at %p\n", d1, s1, p1);
  d2 = strtod(s2, &p1);
  printf("the number is %.2lf; the pointer is now %p; string is at %p\n", d2, s2, p1);
}

这个的输出是:

The number is 123.45; the pointer is now 0x400668; string is at 0x40066e
The number is 0.00; the pointer is now 0x400670; string is at 0x400670

如您所见,在读取垃圾时,返回的指针指向字符串的开头 - 表示“失败”。成功时,指针指向“我停止阅读的地方”,即“在成功将一个字符串转换为双精度之后。

于 2013-07-10T16:58:30.793 回答
0

如果您想确保在线上没有垃圾,您可以使用该%n指令找出转换停止的位置并决定如何处理在线上的后续内容:

char  riga[LUNRIGA];
float numeri[NUM_VALUES];
int   offset;
int   i;

for (i = 0; i < NUM_VALUES && fgets(riga, sizeof(riga), f) != NULL; i++)
{
    int r = sscanf(riga, "%f%n", &numeri[i], &offset);
    if (r == 1 && riga[offset] == '\n')
        printf("OK (got %f from <<%s>>\n", numeri[i], riga);
    else
    {
        printf("Error processing <<%s>>\n", riga);
        return 1; 
    }    
}

您可以在 之前进行一些额外的处理sscanf(),例如检查您是否读取了换行符(因此没有多余的超长行仍然需要读取)并删除换行符(但是您需要更改条件)。

请注意 的使用,以及通过在代码上施加循环来sizeof(riga)检查是否溢出,以及在打印的每条消息的末尾是否存在换行符。numerifor

于 2013-07-10T17:09:04.663 回答