簡體   English   中英

sscanf和正確的格式文件

[英]sscanf and correct format file

我對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; 
      }    
 }

眾所周知, sscanf對輸入很挑剔。 使用strtodstrtol會帶來更好的運氣-即使后面跟着垃圾,它們也可以讀取值。 更改您的代碼,如下所示:

#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您可能想看看這是否確實是您想要的,或者您是否想在每次獲得有效數字時都加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

如您所見,讀取垃圾時,返回的指針指向字符串的開頭-表示“失敗”。 成功時,指針指向“我停止讀取的位置”,即“成功將字符串的一部分轉換為雙精度之后”。

如果您想確定線路上沒有垃圾,可以使用%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) ,並通過在代碼上施加for循環來檢查是否不溢出numeri ,並在每條打印的消息末尾添加換行符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM