C# - Hur använder jag while-loopen för att validera input?

Permalänk

C# - Hur använder jag while-loopen för att validera input?

Hej!
Jag vill att följande loop ska också returnera något om användaren skriver in tecken som inte är siffror.
Alltså typ "Du måste använda siffror"!
Och så får man chansen att skriva in en gång till.

I nuläget har jag bara fått till att det blir ett felmeddelande om lägger in något som är högre än 8 eller lägre en 1.

Jag har provat att lägga till if statements för detta inom loopen men jag får liksom inte till det - tips någon?

{ Console.WriteLine("Hur många vill du välja?"); string numberString = Console.ReadLine(); int numberOf = int.Parse(numberString); bool result = false; while (!result) { if (Int32.TryParse(numberString, out numberOf)) { if (numberOf < 1 || numberOf > 8) { Console.WriteLine("Du måste välja en siffra mellan 1 och 8."); numberString = Console.ReadLine(); } else { result = true; Console.WriteLine("Du har valt " + numberOf ); Console.ReadKey(true); } } }

Permalänk
Medlem
Skrivet av Manda_555:

Hej!
Jag vill att följande loop ska också returnera något om användaren skriver in tecken som inte är siffror.
Alltså typ "Du måste använda siffror"!
Och så får man chansen att skriva in en gång till.

I nuläget har jag bara fått till att det blir ett felmeddelande om lägger in något som är högre än 8 eller lägre en 1.

Jag har provat att lägga till if statements för detta inom loopen men jag får liksom inte till det - tips någon?

{ Console.WriteLine("Hur många vill du välja?"); string numberString = Console.ReadLine(); int numberOf = int.Parse(numberString); bool result = false; while (!result) { if (Int32.TryParse(numberString, out numberOf)) { if (numberOf < 1 || numberOf > 8) { Console.WriteLine("Du måste välja en siffra mellan 1 och 8."); numberString = Console.ReadLine(); } else { result = true; Console.WriteLine("Du har valt " + numberOf ); Console.ReadKey(true); } } }

En else-sats till 'if (Int32.TryParse(numberString, out numberOf))'?

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem
Skrivet av Manda_555:

Hej!
Jag vill att följande loop ska också returnera något om användaren skriver in tecken som inte är siffror.
Alltså typ "Du måste använda siffror"!
Och så får man chansen att skriva in en gång till.

I nuläget har jag bara fått till att det blir ett felmeddelande om lägger in något som är högre än 8 eller lägre en 1.

Jag har provat att lägga till if statements för detta inom loopen men jag får liksom inte till det - tips någon?

{ Console.WriteLine("Hur många vill du välja?"); string numberString = Console.ReadLine(); int numberOf = int.Parse(numberString);

Din första konvertering kommer ju misslyckas och programmet krascha om du inte matar in ett numeriskt värde. Den fyller heller ingen funktion. TryParse är det du ska använda men du kan ju förenkla för dig genom att antingen skapa en funktion som testar om värdet går att konvertera till en int eller en funktion som exempelvis returnerar -1 om det inte är ett numeriskt värde.

Permalänk
Medlem
Skrivet av Mordekai:

Din första konvertering kommer ju misslyckas och programmet krascha om du inte matar in ett numeriskt värde. Den fyller heller ingen funktion. TryParse är det du ska använda men du kan ju förenkla för dig genom att antingen skapa en funktion som testar om värdet går att konvertera till en int eller en funktion som exempelvis returnerar -1 om det inte är ett numeriskt värde.

Bra där, lade inte märke till att det konverterades flera ggr.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem

Så här kan det se ut;

public static void MyMain() { int numberOf = 0; while (numberOf<1 || numberOf>8) { //Här skulle jag lägga in en Console.Clear() Console.WriteLine("Hur många vill du välja?"); string numberString = Console.ReadLine(); numberOf = ToInt(numberString); if (numberOf<1 || numberOf>8) { Console.WriteLine("Du måste välja en siffra mellan 1 och 8."); //Om du lagt in en Console.Clear() kan du behöva lägga in något som pausar programmet en stund som en Console.Beep() } } Console.WriteLine("Du har valt " + numberOf.ToString()); Console.ReadKey(true); } private static int ToInt(string s,int errorValue=-1) { //Den här funkltionen har ett defaultvärde på -1 för errorValue, dvs parametern behöver inte skickas med och parametern får då värdet -1. int tried; bool test = int.TryParse(s, out tried); if (test) { //Konvertering till int lyckades return tried; } else { //Konvertering till int misslyckades return errorValue; } }

Permalänk

Följdfråga

@Mordekai:

Tack för svar!
Jag är dock väldigt mycket nybörjare så hänger inte riktigt med hela vägen...

Finns det något enklare sätt att göra det med den koden jag har?

Och kan du förklara varför följande inte skulle fungera?

En else-sats till 'if (Int32.TryParse(numberString, out numberOf))

Permalänk
Medlem
Skrivet av Manda_555:

@Mordekai:

Tack för svar!
Jag är dock väldigt mycket nybörjare så hänger inte riktigt med hela vägen...

Finns det något enklare sätt att göra det med den koden jag har?

Och kan du förklara varför följande inte skulle fungera?

En else-sats till 'if (Int32.TryParse(numberString, out numberOf))

//Ta bort dessa två rader, de ska ligga inne i while loopen //Console.WriteLine("Hur många vill du välja?"); //string numberString = Console.ReadLine(); //Den här raden skall också bort, det är den som gör att programmet kraschar om du matar in ickenumeriska värden //int numberOf = int.Parse(numberString); bool result = false; //Lägg till denna rad innan loopen så du kommer åt värdet efter loopen int numberOf; while (!result) { //Lägg till dessa två rader inne i loopen string numberString = Console.ReadLine(); Console.WriteLine("Hur många vill du välja?"); if (Int32.TryParse(numberString, out numberOf)) { if (numberOf < 1 || numberOf > 8) { Console.WriteLine("Du måste välja en siffra mellan 1 och 8."); //Ta bort den här raden eftersom vi gör det när vi kommer tillbaka till starten av loopen //numberString = Console.ReadLine(); //För snygghets skull, kör en beep och en Console.Clear() Console.Beep(500, 500); Console.Clear(); } else { result = true; Console.WriteLine("Du har valt " + numberOf); Console.ReadKey(true); } } }

Det vanligaste nybörjarfelet är att man tänker att man skall ha med sig värden in i while loopen och gör en massa saker både i loopen och innan, försök undvik det.

Permalänk
Medlem

Som det påpekats, du försöker konvertera till ett nummer utan TryParse första gången innan din loop, vilket kraschar programmet om du skriver något annat än en siffra.

Mitt tips är att lägga in dina två första rader (som läser in vad användaren skriver) in i while-loopen ovanför din TryParse if-sats. Det gör att varje gång din TryParse misslyckas så går fortsätter while-loopen och frågar användaren igen.

Sitter på mobilen så kan inte svara mycket mer utförligare tyvärr

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av Jackbob:

Som det påpekats, du försöker konvertera till ett nummer utan TryParse första gången innan din loop, vilket kraschar programmet om du skriver något annat än en siffra.

Mitt tips är att lägga in dina två första rader (som läser in vad användaren skriver) in i while-loopen ovanför din TryParse if-sats. Det gör att varje gång din TryParse misslyckas så går fortsätter while-loopen och frågar användaren igen.

Sitter på mobilen så kan inte svara mycket mer utförligare tyvärr

Skickades från m.sweclockers.com

Exakt.

Permalänk
Medlem
Skrivet av Manda_555:

En else-sats till 'if (Int32.TryParse(numberString, out numberOf))

Missade ju denna...

//Ta bort dessa två rader, de ska ligga inne i while loopen //Console.WriteLine("Hur många vill du välja?"); //string numberString = Console.ReadLine(); //Den här raden skall också bort, det är den som gör att programmet kraschar om du matar in ickenumeriska värden //int numberOf = int.Parse(numberString); bool result = false; //Lägg till denna rad innan loopen så du kommer åt värdet efter loopen int numberOf; while (!result) { //Lägg till dessa två rader inne i loopen string numberString = Console.ReadLine(); Console.WriteLine("Hur många vill du välja?"); if (Int32.TryParse(numberString, out numberOf)) { if (numberOf < 1 || numberOf > 8) { Console.WriteLine("Du måste välja en siffra mellan 1 och 8."); //Ta bort den här raden eftersom vi gör det när vi kommer tillbaka till starten av loopen //numberString = Console.ReadLine(); //För snyggets skull, kör en beep och en Console.Clear() Console.Beep(500, 500); Console.Clear(); } else { result = true; Console.WriteLine("Du har valt " + numberOf); Console.ReadKey(true); } } //Nytt else-block om inmatningen inte var numerisk else { Console.WriteLine("Du måste välja en SIFFRA mellan 1 och 8."); Console.Beep(1000, 500); Console.Clear(); } }

Sedan tycker jag det är lite ofint att skriva;
Console.WriteLine("Du har valt " + numberOf);
Jag tycker man ska skriva;
Console.WriteLine("Du har valt " + numberOf.ToString());

Nu har du fått en del hjälp, nu tycker jag du borde skriva om den att använda Console.ReadKey() istället för Console.ReadLine() eftersom du bara ska ha in ett tecken och användaren slipper trycka enter.

Permalänk
Medlem
Skrivet av Mordekai:

Sedan tycker jag det är lite ofint att skriva;
Console.WriteLine("Du har valt " + numberOf);
Jag tycker man ska skriva;
Console.WriteLine("Du har valt " + numberOf.ToString());

Det där är ju en smakfråga, jag skulle personligen föredra:

Console.WriteLine($"Du har valt {numberOf}");

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem

Du kan bryta ut validering i en egen metod som du anropar där du behöver det.

public int InputToInt() { int num; while(!int.TryParse(Console.ReadLine(), out num)) { Console.WriteLine("Du måste ange ett heltal"); } return num; } int numberOf = InputToInt();

Permalänk
Medlem
Skrivet av zaibuf:

Du kan bryta ut validering i en egen metod.

public int InputToInt() { int num; while(!int.TryParse(Console.ReadLine(), out num)) { Console.WriteLine("Ange ett tal"); } return num; }

Fast det där är ju inte validering i en egen metod? Det där är inläsning, validering och upprepade försök i en och samma metod.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk
Medlem
Skrivet av evil penguin:

Fast det där är ju inte validering i en egen metod? Det där är inläsning, validering och upprepade försök i en och samma metod.

Var ett exempel på hur man kan använda en while-loopen för validering.
Du bryter ut Tryparsen för inputen i en egen metod som du kan anropa på flera ställen i programmet, det är valderingen för att den kräver att du anger ett heltal för att komma vidare i programmet.
Kan ju också skicka in en sträng som anpassar felmeddelandet om man vill göra det mer flexibelt.