TL; DR scanner.skip("\\R")
Her scanner.newLine()
çağrıdan önce kullanın , sonra:
scanner.next()
scanner.next*TYPE*()
yöntem.
Bilmeniz gerekenler:
Birkaç satırı temsil eden metin, satırlar arasında yazdırılamayan karakterler de içerir (bunlara satır ayırıcılar diyoruz)
- satır başı (CR - inç olarak gösterilen Dize değişmez değerleri
"\r"
)
- satır besleme (LF - olarak gösterilen Dize değişmez değerleri
"\n"
)
Konsoldan veri okurken, kullanıcının yanıtını yazmasına izin verir ve bittiğinde bir şekilde bu gerçeği doğrulaması gerekir . Bunun için kullanıcının klavyede "enter" / "return" tuşuna basması gerekir.
Önemli olan, kullanıcı verilerinin standart girdiye ( System.in
okunmasıyla temsil edilir) yerleştirilmesinin yanında, bu anahtarın Scanner
ayrıca işletim sistemine bağlı satır ayırıcıları (Windows için olduğu gibi) göndermesidir \r\n
.
Bu nedenle, kullanıcıdan değer istendiğinde age
ve kullanıcı türü 42 ve enter tuşuna bastığınızda , standart girdi içerecektir "42\r\n"
.
Sorun
Scanner#nextInt
(ve diğer yöntemler) Tarayıcı izin vermez tüketmek bu satırları ayırmak. Bunları okuyacaktır (Tarayıcı, boşluktan bakacak değerden daha fazla rakam gösteren kullanıcıdan başka basamak olmadığını nasıl bilebilir ?) Ve bunları standart girdiden kaldıracak, ancak bu satır ayırıcılarını dahili olarak önbelleğe alacaktır . Hatırlamamız gereken şey, tüm Tarayıcı yöntemlerinin önbelleğe alınan metinden başlayarak her zaman taramasıdır. Scanner#nextType
System.in
age
Artık satır ayırıcılar (veya akış sonu) bulana kadarScanner#nextLine()
tüm karakterleri toplar ve döndürür . Ancak, konsoldan numarayı okuduktan sonra satır ayırıcılar hemen Scanner'ın önbelleğinde bulunduğundan, boş String döndürür, yani Tarayıcı bu satır ayırıcılarından (veya akış sonundan) önce herhangi bir karakter bulamadı.
BTW ayrıca bu hat ayırıcılarını da tüketir .
nextLine
Çözüm
Bu nedenle, sonuç olarak boş dizeden kaçınırken sayı ve ardından tüm satır için sormak istediğinizde nextLine
,
nextInt
Tarayıcı önbelleğinden
kalan satır ayırıcısını tüket
- arıyor
nextLine
,
- veya IMO'nun daha okunabilir bir yolu, arayarak
skip("\\R")
veya skip("\r\n|\r|\n")
Tarayıcının hat ayırıcıyla eşleşen parçayı atlamasına izin vermek olabilir (hakkında daha fazla bilgi \R
: https://stackoverflow.com/a/31060125 )
- hiç
nextInt
(ya next
da herhangi bir nextTYPE
yöntem) kullanmayın . Bunun yerine, tüm veri hattını-satır kullanılarak okundu nextLine
Her bir çizgiden ve ayrıştırma numaraları gibi uygun tip (bir satır varsayarak tek sayı içerir) int
ile Integer.parseInt
.
BTW : yöntemler, tarayıcı tarafından önbelleğe alınanlar da dahil olmak üzere, bir sonraki sınırlayıcı olmayan değeri (jeton) bulana kadar sınırlayıcıları (varsayılan olarak sekmeler, satır ayırıcılar gibi tüm boşluklar) atlayabilir . Kod benzeri girişler için teşekkürlerScanner#nextType
"42\r\n\r\n321\r\n\r\n\r\nfoobar"
int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();
uygun şekilde atayabilecektir num1=42
num2=321
name=foobar
.