的原因,它是怎麼回事「瘋狂」如下。當scanf
失敗以a
作爲數字讀取(因爲它不是數字,很明顯),它不會前進文件指針。
這就是爲什麼你不應該一般使用scanf
操作,故障可能離開文件指針在一個不確定的位置(例如,如果你只在3月12日的項目掃描)。
的另一個原因是,scanf
意思是「掃描格式化」,你將很難找到什麼比用戶輸入更多格式化。
不管怎樣,回到失敗。由於文件指針不先進,下次你再來做fscanf
,它會嘗試讀取a
再次(又一遍)。
如果你想爲處理用戶輸入一個體面的功能,那沒有比這裏:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
這將用戶的輸入線,防溢保護(不像gets
或scanf
無界"%s"
)。
這也刷新到行結束時,如果輸入太長,這將影響下次輸入操作停止線的其餘部分。
然後,您可以sscanf
緩衝你的心臟的內容沒有任何的擔憂重新文件指針。
下面的測試程序演示瞭如何使用這樣的:
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
順便說一句,你可能要重新審視你的邏輯,有效大小的房間。你現在有將允許一個房間由-42英尺:-)
輸入爲7這也是通常不是好的形式依靠輸出值被設定爲在進入特定的值。如果輸入時長度和寬度爲(例如)3和4,則此功能將立即退出,而不要求用戶輸入。
第一個問題可以通過使用||
代替&&
被固定。第二種方法是在函數開始時將變量初始化爲0,以便輸入循環。
爲了完整起見,如果你把該原始片段上方具有以下(在include
報表及getLine()
功能)略作修改get_room_size()
功能:
static void get_room_size(char room_id, int * length, int * width) {
char buff[100];
*length = *width = 0;
while ((*length <= 0) || (*width <= 0)) {
printf("Enter length and width of room %c in feet: ", room_id);
int rc = getLine (NULL, buff, sizeof (buff));
if (rc == NO_INPUT) {
printf ("\nEnd of file encountered.\n");
return;
}
if (rc == TOO_LONG) {
printf ("\nInput too long, please retry.\n");
continue;
}
if (sscanf(buff, "%d,%d", length, width) != 2) {
*length = *width = 0;
printf ("\nInput not in desired form (<number>,<number>), "
"please retry.\n");
continue;
}
if ((*length <=0) || (*width <= 0)) {
*length = *width = 0;
printf ("\nBoth length and width must be greater than zero, "
"please retry.\n");
}
}
}
和非常簡單的測試main()
,你」我將看到一個完整的程序,展示如何去做。
int main (void) {
int len, wid;
get_room_size ('x', &len, &wid);
printf ("Length is %d, width is %d.\n", len, wid);
return 0;
}
你有沒有代碼,可以讀取「一個',所以它永遠不會被讀取。 –