Saya mencoba mengerjakan fungsi yang mengambil input, batas karakter minimum dan batas karakter maksimum. Saya harus menerima input dan menghitung huruf meskipun ada 2 kata atau lebih, dan Saya melihat orang-orang berkata scanf("%30[^\n]%*c") akan berhasil. Namun, ini hanya berfungsi jika ini adalah input pertama, tidak lebih. Jika ada input di atas, itu hanya akan mengakhiri baris, meninggalkan hitungan sebagai nol, dan menjalankan loop tanpa batas. Ada yang tahu kenapa?

CATATAN: Saya tidak dapat menggunakan apa pun dari file header .

{
    int n = 1;
    
    while (n == 1)
    {
        int count = 0;
        scanf("%30[^\n]%*c", input);
        while (input[count] != '\0')
        {
            count++;
        }
        if (minimum == maximum)
        {
            if (count > maximum)
            {
                printf("String length must be exactly %d chars: ", minimum);
            }
            else if (count == minimum)
            {
                n = 0;
                return input;
            }
            else if (count < minimum)
            {
                printf("String length must be exactly %d chars: ", minimum);
            }
        }
        else 
        {
            if (count > maximum)
            {
                printf("String length must be no more than %d chars: ", maximum);
            }
            else if (minimum <= count && count <= maximum)
            {
                n = 0;
                return input;
            }
            else if (count < minimum)
            {
                printf("String length must be between %d and %d chars: ", minimum, maximum);
            }
        }
    }
}
c
1
Redgehog 3 April 2021, 13:47

1 menjawab

Jawaban Terbaik

Masalah dengan scanf("%30[^\n]%*c", input); adalah gagal jika byte baru dari stdin adalah baris baru, mengembalikan 0 dan membiarkan input tidak berubah, berpotensi tidak diinisialisasi, menyebabkan sisa kode menjadi memiliki perilaku yang tidak terdefinisi.

Perhatikan juga bahwa format ini akan menyebabkan scanf() membaca dan membuang byte yang tertunda setelah konversi, baik baris baru, yang merupakan maksud Anda atau karakter ke-31 apa pun yang diketikkan oleh pengguna pada baris input.

Anda harus menguji nilai kembalian scanf() untuk mendeteksi kesalahan konversi dan/atau akhir file dan hanya memindai larik jika scanf() mengembalikan 1.

Anda harus membuang byte tambahan di akhir baris dengan loop:

int c;
while ((c = getchar()) != EOF && c != '\n')
    continue;

Atau dengan scanf():

scanf("%*[^\n]");  // discard the rest of the input line if any
scanf("%*c");      // discard the newline if any.

Untuk menghilangkan baris baru yang tertunda yang tersisa dari panggilan sebelumnya ke scanf(), Anda dapat menulis:

int c;
if ((c = getchar()) != '\n')
    ungetc(c, stdin);

Atau menggunakan scanf:

scanf("%1*[\n]");  // read and discard at most 1 newline byte
0
chqrlie 3 April 2021, 11:29