2016-10-08 28 views
5

我一直在測試這個結構,我得到關於使用gets的警告。有人提到用fgets代替,並用'\0'代替。任何建議如何改變我的代碼來做到這一點?替換獲取()與fgets()

void regCars(Car reg[], int *pNrOfCars) { 
    char again[WORDLENGTH] = "yes", model[WORDLENGTH], tmp[WORDLENGTH]; 
    int year, milage; 

    while (strcmp(again, "yes") == 0) { 
     printf("Enter model:"); 
     gets(model); 
     printf("Enter Year:"); 
     gets(tmp); 
     year = atoi(tmp); 
     printf("Enter milage:"); 
     gets(tmp); 
     milage = atoi(tmp); 
     reg[*pNrOfCars] = createCar(model, year, milage); 
     (*pNrOfCars)++; 
     printf("Continue? (yes/no)"); 
     gets(again); 
    } 
} 

回答

0

您可以編寫一個效用函數mygets()是需要兩個參數:一個指向目標數組,其大小:

char *mygets(char *dest, size_t size) { 
    /* read a line from standard input and strip the linefeed if any */ 
    if (fgets(dest, size, stdin)) { 
     dest[strcspn(dest, "\n")] = '\0'); 
     return dest; 
    } 
    return NULL; 
} 

void regCars(Car reg[], int *pNrOfCars) { 
    char model[WORDLENGTH], tmp[WORDLENGTH]; 
    int year, milage; 

    for (;;) { 
     printf("Enter model:"); 
     if (!mygets(model, sizeof mode)) 
      break; 
     printf("Enter year:"); 
     if (!mygets(tmp, sizeof tmp)) 
      break; 
     year = atoi(tmp); 
     printf("Enter milage:"); 
     if (!mygets(tmp, sizeof tmp)) 
      break; 
     milage = atoi(tmp); 
     reg[*pNrOfCars] = createCar(model, year, milage); 
     (*pNrOfCars)++; 
     printf("Continue? (yes/no)"); 
     if (!mygets(tmp, sizeof(tmp)) 
      break; 
     if (strcmp(again, "yes") != 0) 
      break; 
    } 
} 

注意,您可以用prompt()功能輸出的因式分解更多的代碼提問並讀取響應:

char *prompt(const char *message, char *dest, size_t size) { 
    printf("%s ", message); 
    fflush(stdout); 
    /* read a line from standard input and strip the linefeed if any */ 
    if (fgets(dest, size, stdin)) { 
     dest[strcspn(dest, "\n")] = '\0'); 
     return dest; 
    } 
    return NULL; 
} 

void regCars(Car reg[], int *pNrOfCars) { 
    char model[WORDLENGTH], tmp[WORDLENGTH]; 
    int year, milage; 

    for (;;) { 
     if (!prompt("Enter model:", model, sizeof mode)) 
      break; 
     if (!prompt("Enter year:", tmp, sizeof tmp)) 
      break; 
     year = atoi(tmp); 
     if (!prompt("Enter milage:", tmp, sizeof tmp)) 
      break; 
     milage = atoi(tmp); 
     reg[*pNrOfCars] = createCar(model, year, milage); 
     (*pNrOfCars)++; 
     if (!prompt("Continue? (yes/no)", tmp, sizeof(tmp)) 
      break; 
     if (strcmp(again, "yes") != 0) 
      break; 
    } 
} 

另請注意,此功能應取大小爲reg數組在停止提示時輸入更多數據。按照當前規定,它具有與gets()相同的缺點,意外的輸入會導致未定義的行爲。

+0

@Alex:你介意對你接受的答案進行投票嗎? – chqrlie

0

只是做例如

if (NULL != fgets(model, WORDLENGTH, stdin)) /* Read the string. */ 
{ 
    model[strcspn(model, "\r\n")] = '\0'; /* Cut off \n and/or \r, if any. */ 
} 
+0

我認爲這只是模型,如果我有乘以int和char,是否有一個函數可以查看所有這些,並替換\ n? – xxFlashxx

+0

@Alex:'fgets()'(以及'get()')只讀取「字符串」。爲了閱讀「年份」,您可以使用'gets(tmp)',它可以如圖所示進行替換。 – alk

+0

所以我插入if語句後fgets(模型)? – xxFlashxx

1

這是一個小一點小技巧比它的外觀。用fgets()替換get就沒有太大的意義,如果你在超長輸入中處理一個截斷的行並將其作爲有效處理。你只是用錯誤的行爲取代了未定義的行爲。

if(fgets(line, sizeof(line), fp)) 
{ 
    if(!strchr(line, '\n')) 
    { 
     /* line is too long, what you do is up to you, but normally 
     we will discard it */ 
     int ch; 

     while((ch = fgetc(fp)) != EOF) 
     if(ch == '\n') 
      break; 

    } 
    else 
    { 
     /* line is a normal line with a trailing '\n' (gets trims the '\n')   */ 
    } 
} 
+0

沒有必要放棄長行......並且在由計算機程序編寫的文本文件中長行很常見。 'fgets()'可以讀取它們......它只需要更多的調用和邏輯來處理它。 – Peter

+0

如果有效行不受限制,fgets()不是您選擇的輸入函數。但是,當然,這種過長的路線意味着什麼是由情況決定的,有時候放棄它是錯誤的。然而,無聲地截斷並將剩餘部分與實線區分開幾乎從不是正確的行爲。 –