2016-10-08 26 views
5

Bu yapıyı test ediyorum ve gets'u kullanma konusunda uyarıyorum. Birisi bunun yerine fgets kullandı ve '\0' ile sonunu değiştirdi. Bunu yapmak için kodumu nasıl değiştirebileceğime dair herhangi bir öneriniz var mı?Alır() with 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); 
    } 
} 

cevap

0

Bir fayda fonksiyonu 2 argüman alır mygets() yazabilir

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

Ayrıca, bu fonksiyonboyutunu almalıdır unutmayın: soru ve yanıtı okurdizisi dolduğunda daha fazla girdi sorulmasını durdurmak için. Şu anda belirtildiği gibi, gets() ile aynı eksikliğe sahip, beklenmedik giriş tanımsız davranışa neden olacaktır.

+0

@Alex: kabul ettiğin cevabı oylayacak mısın? – chqrlie

0

Sadece örnek

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

Sanırım bu sadece model için yapacaktır, int's ve char'ı çoğaltırsam, hepsine bakıp \ n? – xxFlashxx

+0

@Alex: 'fgets()' (''() 'nin yanı sıra yalnızca" dizeleri "okur. "Yıl" ı okumak için, gösterildiği gibi değiştirilebilen 'gets (tmp)' kullanırsınız. – alk

+0

bu yüzden if ifadesini fgets (model) sonrası hemen ekliyorum? – xxFlashxx

1

Göründüğünden daha biraz tricker var yapmak. Sadece uzun bir giriş üzerinde kesilmiş bir çizgi işleyip geçerli olarak ele alırsanız, sadece fgets() ile değiştirmenin yerini almanın pek bir anlamı yoktur. Sadece tanımlanmamış davranışları yanlış davranışla değiştirdiniz. bir işaretçi hedef dizi ve bunun boyutu: Eğer çıktılar bir prompt() fonksiyonu ile daha fazla kod çarpanlara olabilir

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

Not

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

Sadece uzun satırları atmak gerekmiyor ... ve bilgisayar programları tarafından yazılan metin dosyalarında uzun çizgiler sık ​​sık ortaya çıkıyor. 'fgets()' onları okuyabilir ... sadece daha fazla çağrı alır ve bunu işlemek için mantık. – Peter

+0

Geçerli çizgiler sınırsızsa, fgets() seçtiğiniz giriş işleviniz değildir. Fakat elbette ki aşırı uzun bir çizgi, durum tarafından belirlenir ve bazen atmak yanlıştır. Sessizce kesip kalan ve kalan çizgiyi tam bir çizgiden ayırt edememek neredeyse hiç doğru davranış değildir. –