第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

scanf為何失敗?

scanf為何失???

C
手掌心 2019-12-06 12:52:09
當我編寫此代碼時,編譯并運行:int x;   scanf ("%d", &x);  while (x!=4) {      scanf ("%d", &x);  }當插入char或小于4的雙數時,它將進入無限循環(huán)。當插入大于4的double時終止。有什么解釋嗎?
查看完整描述

3 回答

?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

根據C語言標準(n1256):


7.19.6.2 fscanf函數

...

4 fscanf函數依次執(zhí)行格式的每個指令。如果指令失敗,如下所述,函數將返回。失敗描述為輸入失?。ㄓ捎诎l(fā)生編碼錯誤或輸入字符不可用)或匹配失?。ㄓ捎诓贿m當的輸入)。

...

7作為轉換規(guī)范的指令定義了一組匹配的輸入序列,如下文針對每個說明符所述。轉換說明將按照以下步驟執(zhí)行:


8除非輸入規(guī)范中包含[,c或n說明符,否則將跳過輸入的空白字符(由isspace函數指定)。250)


9從流中讀取一個輸入項,除非規(guī)范包括n個說明符。輸入項定義為最長的輸入字符序列,該序列不超過任何指定的字段寬度,并且是匹配輸入序列的前綴,或者是匹配輸入序列的前綴。251)輸入項之后的第一個字符(如果有)保持未讀狀態(tài)。如果輸入項的長度為零,則該指令的執(zhí)行失敗;否則,該指令的執(zhí)行失敗。除非文件末尾,編碼錯誤或讀取錯誤阻止了來自流的輸入,否則此條件是匹配失敗,在這種情況下,這是輸入失敗。


10除非是%說明符,否則輸入項(或者,如果是%n指令,即輸入字符數)轉換為適合轉換說明符的類型。如果輸入項不是匹配序列,則指令的執(zhí)行失?。捍藯l件是匹配失敗。除非用*表示禁止分配,否則轉換結果將放置在尚未收到轉換結果的format參數后面的第一個參數指向的對象中。如果該對象沒有適當的類型,或者無法在對象中表示轉換結果,則該行為是不確定的。

在第10段中添加了重點。%d轉換說明符希望輸入文本的格式設置為十進制整數。如果不是,則轉換失敗,并且導致轉換失敗的字符保留在輸入流中。scanf()使用%d轉換說明符進一步調用將會阻塞相同的字符。


scanf()返回成功分配的數量;您需要檢查此結果以查看轉換是否成功,如下所示:


int x = 0;

while (x != 4)

{

  int result = scanf("%d", &x);

  if (result != 1)

  {

    printf("Last call to scanf() failed; exiting\n");

    break;

  }

}

不幸的是,您仍然將錯誤的輸入卡在輸入流中。有許多策略可以解決這個問題。您可以使用刪除令人反感的字符,getchar然后重試:


while (x != 4)

{

  int tmp;

  if (scanf("%d", &tmp) == 0)

    getchar();

  else

    x = tmp;

}

或者,您可以嘗試讀取下一個換行符,假設所有剩余的輸入都為b0rked:


while (x != 4)

{

  int tmp;

  if (scanf("%d", &tmp) == 0)

    while (getchar() != '\n')

      ;

  else

    x = tmp;

}

或者,您可以嘗試將輸入讀取為文本,然后使用strtol()(我的首選技術)將其轉換為整數:


char input[SOME_SIZE];

int x = 0;

...

while (x != 4)

{

  if (fgets(input, sizeof input, stdin))

  {

    char *check;

    int tmp = (int) strtol(input, &check, 10);

    if (!isspace(*check) && *check != 0)

    {

      printf("%s is not a valid integer: try again\n", input);

    }

    else

    {

      x = tmp;

    }

  }

  else

  {

    printf("Read error on standard input\n");

    break;

  }

}

這需要做更多的工作,但可以讓您在將錯誤的輸入分配給之前捕獲錯誤的輸入x。


查看完整回答
反對 回復 2019-12-06
?
桃花長相依

TA貢獻1860條經驗 獲得超8個贊

您無需檢查scanf實際是否成功,因此會陷入錯誤。對于每個循環(huán),scanf都會嘗試讀取并失敗。

scanf 返回成功讀取項的數量,因此將循環(huán)修改為如下形式 while (x!=4) { if (scanf("%d",&x) != 1) break; }


查看完整回答
反對 回復 2019-12-06
?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

當scanf在輸入流中的特定位置停止掃描時,它將永遠不會推進該流,因此下一個scanf將再次嘗試相同的錯誤...并再次嘗試...


輸入:42 23 foo ...

scanf:^

x 42

scanf:^

x 23

scanf:^

x無法使用

scanf:^

x無法使用

scanf:^

x無法使用

scanf:^

x無法使用

scanf:^

x無法使用


查看完整回答
反對 回復 2019-12-06
  • 3 回答
  • 0 關注
  • 907 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號