scanf () yeni satır karakterini arabellekte bırakır


93

Aşağıdaki programım var:

C kitabında okuduğum gibi, yazar scanf()arabellekte yeni bir satır karakteri bıraktığını, bu nedenle programın kullanıcının verileri girmesi için 4. satırda durmadığını, bunun yerine yeni satır karakterini c2'de sakladığını ve 5. satır.

Bu doğru mu?

Ancak, bu yalnızca charveri türlerinde mi olur ? Çünkü intveri türlerinde bu sorunu 1., 2., 3. satırlardaki gibi görmedim. Doğru mu?


Bazen tek bir karakter için fflush(stdin)çağrılmadan önce kullanılabileceği önerilir scanf(). Artıları ve eksileri ve bu yöntemin alternatifleri hakkında bir tartışma için lütfen Kullanmafflush(stdin) bölümünü okuyun (bu, Windows'ta az çok çalışır ve diğer yerlerde işe yaramaz).
Jonathan Leffler

Lütfen hangi kitaptan bahsettiğinizi bize bildirir misiniz?
surya kiran

Yanıtlar:


82

scanf()Karakterleri dışındaki dönüşümleri ayrıştırmak denemeden önce otomatik boşluk lider fonksiyon atlar. Karakter biçimleri (öncelikle %c; ayrıca tarama kümeleri %[…]- ve %n) istisnadır; boşlukları atlamazlar.

Kullan " %c"isteğe bağlı beyaz boşluk atlamak için lider boş ile. scanf()Biçim dizesinde sonda bir boşluk kullanmayın .

Not bu yine, giriş akımının kalan boşluk sonda tüketmez olduğu, hatta hattının sonunda, bu nedenle, aynı zamanda, eğer kullanarak bu dikkat getchar()ya da fgets()aynı giriş akımında. Sadece , karakter dışı dönüşümler ve diğer karakter dışı dönüşümler için yaptığı gibi, dönüşümlerden önce beyaz boşlukları atlamak için scanf alıyoruz %d.


Boşluk olmayan "yönergelerin" ( POSIX scanf terminolojisini kullanmak için ), içindeki değişmez metin gibi, scanf("order = %d", &order);beyaz boşlukları atlamadığını unutmayın. Değişmez order, okunacak bir sonraki karakterle eşleşmelidir.

Dolayısıyla " order = %d", önceki satırdan bir yeni satırı atlamak, ancak yine de bu soru gibi sabit bir dizede birebir eşleşme istiyorsanız, muhtemelen orayı istersiniz .


9
%c, %n, %[]Lider boşluk tüketmeyin 3 Belirtilen beklentilerdir.
chux - Monica'yı yeniden etkinleştir

@chux Diğer Durumlarda Öyleyse, scanf arabellekteki tüm boşlukları temizler veya girdikleri için onları yok sayar ama hala oradalar mı?
Suraj Jain

@SurajJain Evet,
chux

3
Biçim dizesinde sondaki boşluğascanf() bakın ve biçim dizelerindeki sondaki boşluklarla ilgili bir tartışma için scanf()yalnızca bir kez sormasını beklerken iki kez girdi isteyin . Kötü bir fikir - insan etkileşimi bekliyorsanız şaşırtıcı derecede kötü ve program etkileşimi için kötü.
Jonathan Leffler

32

Kullanın scanf(" %c", &c2);. Bu sorununu çözecektir.


8

Başka bir seçenek ( buradan aldığım ) atama-bastırma seçeneğini kullanarak yeni satırı okuyup atmaktır . Bunu yapmak için, %ve arasında yıldız işareti olan bir karakteri okumak için bir format koyarız c:

scanf daha sonra sonraki karakteri (yani satırsonu) okuyacak, ancak onu herhangi bir işaretçiye atamayacaktır.

Bununla birlikte, sonunda, SSS'nin son seçeneğini ikinci olarak değerlendireceğim :

Veya gereksinimlerinize bağlı olarak, scanf () / getchar () 'ı da unutabilir, kullanıcıdan bir metin satırı almak ve onu kendiniz ayrıştırmak için fgets () kullanabilirsiniz.


3
Bu tekniğin sorunu, kullanıcı adaha sonra boşluk yazıp sonra satırsonu yazarsa, bastırılmış karakter dönüşümünün boşluğu okur ve yine de satırsonunu terk etmesidir. Kullanıcı supercalifragilisticexpialidociousbeklediğiniz zaman yazarsa a, uğraşmanız gereken çok fazla karakteriniz vardır. Sondaki bastırılmış bir dönüşümün de başarılı olup olmadığını asla bilemezsiniz - dönüşte sayılmazlar scanf().
Jonathan Leffler

4

getchar()İkinci aramadan önce kullanın scanf().


1
Bu, kullanıcının başka bir şey yazmaması koşuluyla çalışır - örneğin sondaki boşluklar. Ancak bir sonraki satır int c; while ((c = getchar()) != EOF && c != '\n') ;satırını tarayan bir döngü kadar iyi değildir: (yorumda bulunmadığında üç satıra yazılır). Genellikle yeterlidir; bu kusursuz değildir (ve aptalların bir şeyleri çarpma konusunda çok akıllı olduklarını unutmamalısınız).
Jonathan Leffler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.