Permalänk
Medlem

hjälp med try catch i C#

Tjena,
jag är väldigt ny med programmering och håller på att lära mig c sharp på gymnasienivå. Jag vill få in try catch i programmet så att den endast tolkar heltal vid inmatningen. eftersom den tolkar en string till int och sedan kastar om den till double så undrar jag vart jag ska stoppa in try catch. Om jag till exempel skriver bokstäver ska den ge ett fel medelande som säger t.ex. "obs bara heltal vid inmatning" Är det lättare att göra en metod i detta fall? är inte ute efter en lösning utan snarare tips på hur jag ska gå till väga.
Tack på förhand

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { string result;//används för ja och nej alternativ i den sekundära if statsen bool loop = true; Console.Write("Skriv in temperatur i fahrenheit: ");//skriver ut det som står inan för "" string str = Console.ReadLine();//tolkar input från tangentbord int inmatat = Convert.ToInt32(str);//converterar textsträng till heltal double fahrenheit = (double)inmatat;//en cast som gör om int till double double celsius = FahToCel(fahrenheit);//anropar metoden FahToCel men variabeln fahrenheit som input do // skapar villkor för while loopen { if (fahrenheit == 167) //villkor för while loopen { Console.Write("Optimal temperatur, njut av bastun! tryck på en tangent för att avsluta..."); Console.ReadKey(); break; } else if (163 <= fahrenheit && fahrenheit <= 165) //huvud if-sats { Console.WriteLine("Du skrev in " + celsius + " grader celsius. Det är en godtagbar temperatur"); Console.WriteLine("Vill du försöka få optimal temperatur? J/N"); result = Console.ReadLine(); if (result.Equals("j", StringComparison.OrdinalIgnoreCase) || result.Equals("Ja", StringComparison.OrdinalIgnoreCase)) //sekundär if-sats med alternativ för ja och nej { Console.WriteLine(); Console.Write("skriv in ny temperatur: "); str = Console.ReadLine(); inmatat = Convert.ToInt32(str); fahrenheit = (double)inmatat; celsius = FahToCel(fahrenheit); } else if (result.Equals("n", StringComparison.OrdinalIgnoreCase) || result.Equals("Nej", StringComparison.OrdinalIgnoreCase))//sekundär if sats { Console.Write("Njut av bastun, tryck på en tangent för att avsluta..."); Console.ReadKey(); } } else if (170 <= fahrenheit && fahrenheit <= 1000) { Console.Write("Du angav " + celsius + "det är för varmt, sänk temperaturen."); Console.Write("Skirv in ny lägre temperatur: "); str = Console.ReadLine(); inmatat = Convert.ToInt32(str); fahrenheit = (double)inmatat; celsius = FahToCel(fahrenheit); } else { Console.Write("Du skrev in " + celsius + " grader celsius. Det är för kallt... Öka temperaturen"); Console.WriteLine(); Console.Write("skriv in ny temperatur: "); str = Console.ReadLine(); inmatat = Convert.ToInt32(str); fahrenheit = (double)inmatat; celsius = FahToCel(fahrenheit); } } while (true); } public static double FahToCel(double fah)//metod för att konvertera F till C { double cel = fah = (fah - 32) * 5 / 9; return cel; } } }

Permalänk
Medlem

Kolla in msdn Convert.ToInt32, vid exemplen så använder de try catch.

Permalänk
Hedersmedlem

Om du vill ha stöd för decimaler bör du nog låta bli att konvertera till heltal först (se Convert.ToDouble()), men man kan också använda Double-klassens parse-funktion:

double d = Double.parse("5.3");

Om man inte är säker på att det kommer lyckas finns också en TryParse(), som returnerar true eller false beroende på om konverteringen var giltig.

Permalänk
Medlem

noyce kollade lite där ska försöka få ihop något! Är det en bra ide att trycka in try catch i "do" partiet i loopen eller i början (innan loopen) i detta fallet? tack för svar.

Permalänk
Medlem

@vaasques:

Som Elgot skrev här ovanför, så kommer din kod inte acceptera ett tal med decimaler ifrån inmatningen.

Eftersom du upprepar samma stycke i do loopen x antal gånger skulle jag rekommendera att lägga hela den biten i en egen funktion. Där kan du även köra en try catch. Då kan du ersätta det mesta i if else satsers med ett anrop till denna funktion.

Permalänk
Medlem

@Elgot: tack för svar! enligt läraren så skulle vi konvertera till int först för att visa att vi sedan kan "casta" om den till "double".

skriver in i celsius (heltal) ---> fahrenheit med decimaler

så jag vet inte riktigt om det kommer att gå...

Permalänk
Medlem

@noyce: Okej tack, ska kriga med detta. kommer nog återkomma när jag fastnarmed det. tack för hjälp och kunnande

Permalänk
Medlem

Hur får jag min metod att läsa samt konvertera string till int? har fastnat ordentligt...

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { string result; Console.Write("Skriv in temperatur i fahrenheit: ");//skriver ut det som står inan för "" string str = InputCatchTry; } public static string InputCathcTry(int a) { a = Console.ReadLine(Convert.ToInt32); return a; } } }

Permalänk
Medlem

@vaasques
Något i stil med detta kanske?
Det som händer är följande;
ConvertToInt använder Int.TryParse som returnerar true/false beroende på om det går att konvertera eller ej. Om det går så kommer "num" att få det tilldelade värdet.
Därefter kontrolleras värdet på "result" - d.v.s. bool:en som säger om konverteringen blev lyckad eller ej.

static void Main(string[] args) { string result; Console.Write("Skriv in temperatur i fahrenheit: ");//skriver ut det som står inan för "" ConvertToInt(Console.ReadLine()); } public static void ConvertToInt(string val) { int num; bool result = Int.TryParse(val, out num); if(result) { //Värdet är ett heltal, gör det du ska. } else //Värdet är ej ett heltal, skriv ut felmeddelandet. }

**Ursäktar för formateringen på texten, inte helt lätt att få det snyggt i denna ruta då den ej tillåter [tab].

Visa signatur

NZXT H510 Flow MSI B450 Tomahawk MAX
AMD Ryzen 5800X3D RX 7900XTX Kingston Fury 64GB

Permalänk
Medlem

IMHO så använder man try catch för "oväntade" fel. Att hantera heltal eller ej i detta program är inte oväntat och skall hanteras via t.ex. tryparse eller convert i en IF slinga.

Try catch är bra, men skall användas på rätt sett, inte som en villkors-styrning

// LZ

Permalänk
Medlem

@Pamudas:
Något i denna stil kanske fungerar, har inte testat eller kollat syntax allt för noga dock.
Du behöver såklart även fylla på med din gamla kod, kanske även lägga till något kommando för att avsluta inmatningen i denna funktion.

OBS: Som flera skriver ovan bör du kanske istället kolla på TryParse, för en mer korrekt syntax, visar exempel med det också.

static void Main(string[] args) { string result; double fahrenheit = InputCatchTry("Skriv in temperatur i fahrenheit: "); // double fahrenheit = InputTryParse("Skriv in temperatur i fahrenheit: "); double celsius = FahToCel(fahrenheit); do // skapar villkor för while loopen { // Do stuff here } } public static double InputCatchTry(string msg = null) { if (msg != null) { Console.WriteLine(msg); } string str = Console.ReadLine();//tolkar input från tangentbord try { int inmatat = Convert.ToInt32(str);//converterar textsträng till heltal double fahrenheit = (double)inmatat;//en cast som gör om int till double return fahrenheit; } catch (FormatException) { return InputCatchTry("Du måste ange ett heltal:"); } } public static double InputTryParse(string msg = null) { // Dont output any message if empty msg if (msg != null) { Console.WriteLine(msg); } string str = Console.ReadLine(); // Tolkar input från tangentbord int number; bool result = Int32.TryParse(str, out number); // Talet lagras i number om det är ett heltal (out number) if (result) { double fahrenheit = (double)number; // En cast som gör om int till double return fahrenheit; } // Gör om allt igen om talet inte var giltigt return InputTryParse("Du måste ange ett heltal:"); }

Permalänk
Medlem
Skrivet av noyce:

@Pamudas:
Något i denna stil kanske fungerar, har inte testat eller kollat syntax allt för noga dock.
Du behöver såklart även fylla på med din gamla kod, kanske även lägga till något kommando för att avsluta inmatningen i denna funktion.

OBS: Som flera skriver ovan bör du kanske istället kolla på TryParse, för en mer korrekt syntax, visar exempel med det också.

static void Main(string[] args) { string result; double fahrenheit = InputCatchTry("Skriv in temperatur i fahrenheit: "); // double fahrenheit = InputTryParse("Skriv in temperatur i fahrenheit: "); double celsius = FahToCel(fahrenheit); do // skapar villkor för while loopen { // Do stuff here } } public static double InputCatchTry(string msg = null) { if (msg != null) { Console.WriteLine(msg); } string str = Console.ReadLine();//tolkar input från tangentbord try { int inmatat = Convert.ToInt32(str);//converterar textsträng till heltal double fahrenheit = (double)inmatat;//en cast som gör om int till double return fahrenheit; } catch (FormatException) { return InputCatchTry("Du måste ange ett heltal:"); } } public static double InputTryParse(string msg = null) { // Dont output any message if empty msg if (msg != null) { Console.WriteLine(msg); } string str = Console.ReadLine(); // Tolkar input från tangentbord int number; bool result = Int32.TryParse(str, out number); // Talet lagras i number om det är ett heltal (out number) if (result) { double fahrenheit = (double)number; // En cast som gör om int till double return fahrenheit; } // Gör om allt igen om talet inte var giltigt return InputTryParse("Du måste ange ett heltal:"); }

Kan ju göra såhär så TS ser det du skrev :')
@vaasques

Visa signatur

NZXT H510 Flow MSI B450 Tomahawk MAX
AMD Ryzen 5800X3D RX 7900XTX Kingston Fury 64GB

Permalänk
Medlem

@noyce det funkar alldeles utmärkt, det var exakt så som jag ville få till det. Jag är sjukt tacksam för hjälpen. Det tog ett bra tag att förstå någorlunda vad exakt du gjorde och få det att passa in till resten. men msg !=null.. där har jag svårt att greppa. Vad menas med "null" och när används det? != vet jag att det är "inte lika med" om du har lust kan du förklara mer ingående hur du gjort och tänkt? så att jag förstår det hela rätt.

En sak till: försökte att få else if (163 <= fahrenheit && fahrenheit <= 165 || 168 <= fahrenheit && fahrenheit <= 171)
till en egen if else men då blev det tomt. Jag tog och alltså bort OR operatorn och gjorde en egen else if för
(168 <= fahrenheit && fahrenheit <= 171) men då kom det inte upp något som efter att jag skrev in 168.
Efter att jag använde OR operatorn funkade det utmärkt men jag förstår inte varför...
nu ser koden ut så här och funkar utan fel förutom "else" vad har jag gjort för fel?

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { string result; double fahrenheit = InputCatchTry("Skriv in temperratur i fahrenheit: "); double celsius = FahToCel(fahrenheit);//anropar metoden FahToCel men variabeln fahrenheit som input do // skapar villkor för while loopen { if (fahrenheit == 167) //villkor för while loopen { Console.Write("Du angav " + celsius + " grader celsius. Det är den optimala temperaturen, njut av bastun! tryck på en tangent för att avsluta..."); Console.ReadKey(); break; } else if (0 <= fahrenheit && fahrenheit <= 162) { Console.WriteLine("Du skrev in " + celsius + " grader celsius. Det är för kallt"); fahrenheit = InputCatchTry("Skriv in temperatur: "); celsius = FahToCel(fahrenheit); } else if (163 <= fahrenheit && fahrenheit <= 165 || 168 <= fahrenheit && fahrenheit <= 171) //huvud if-sats { Console.WriteLine("Du skrev in " + celsius + " grader celsius. Det är en godtagbar temperatur"); Console.WriteLine("Vill du försöka få optimal temperatur? J/N"); result = Console.ReadLine(); if (result.Equals("j", StringComparison.OrdinalIgnoreCase) || result.Equals("Ja", StringComparison.OrdinalIgnoreCase)) //sekundär if-sats med alternativ för ja och nej { Console.WriteLine(); fahrenheit = InputCatchTry("skriv in ny temperatur: "); celsius = FahToCel(fahrenheit); } else if (result.Equals("n", StringComparison.OrdinalIgnoreCase) || result.Equals("Nej", StringComparison.OrdinalIgnoreCase))//sekundär if sats { Console.Write("Njut av bastun, tryck på en tangent för att avsluta..."); Console.ReadKey(); break; } else { Console.Write("Du angav " + celsius + "det är för varmt, sänk temperaturen."); fahrenheit = InputCatchTry("Skirv in ny lägre temperatur: "); celsius = FahToCel(fahrenheit); } } } while (true); } public static double InputCatchTry(string msg = null) { if (msg != null) { Console.WriteLine(msg); } string str = Console.ReadLine();//tolkar input från tangentbord try { int inmatat = Convert.ToInt32(str);//converterar textsträng till heltal double fahrenheit = (double)inmatat;//en cast som gör om int till double return fahrenheit; } catch (FormatException) { return InputCatchTry("Du måste ange ett heltal: "); } } public static double FahToCel(double fah)//metod för att konvertera F till C { double cel = fah = (fah - 32) * 5 / 9; return cel; } } }

Tack för att ni har tålamod med mig

Permalänk
Medlem

@vaasques:

Bara kul om jag kan vara till hjälp.
Anledningen till att jag har kontrollen om (msg != null) är för att jag har satt att msg har ett default värde på null i funktionen.
Detta gör att om du vill anropa InputCatchTry(), utan att skicka med ett meddelande så går det bra. Annars hade du behövt skriva något i stil med InputCatchTry(""), en tom sträng.

För att besvara din andra fråga, jag testade att flytta ut den till en egen else if, fungerade utan problem. Var noga med att du lägger den på rätt ställe bara så bör det inte vara några problem. Bara att fråga på om det inte löser sig!

Permalänk
Medlem

@noyce: Jag hade klantat mig med kodblocken, fick allt att fungera nu

bara så att jag fattar det hela rätt nu:

string msg = input i form av string variabel. fråga här, double går ju in i metoden hur kommer det sig?
eftersom double fahrenheit = InputCatchTry("Skriv in temperratur i fahrenheit: ")

"static double" = den typ av variabel som metodens ouput stödjer.

public static double InputCatchTry(string msg= null)
(string msg= null) att strängen saknar något värde.

OM (msg inte är lika med null)
alltså - om string inte saknar värde vilket kan vara vilken input som helst från tangentbord --> skicka vidare till nästa bit kod

förstår jag det rätt eller har jag missuppfattat?

public static double InputCatchTry(string msg= null) { if (msg!= null) { Console.WriteLine(msg); } string str = Console.ReadLine();//tolkar input från tangentbord try { int inmatat = Convert.ToInt32(str);//converterar textsträng till heltal double fahrenheit = (double)inmatat;//en cast som gör om int till double return fahrenheit; } catch (FormatException) { return InputCatchTry("Du måste ange ett heltal: "); } }

//vaasques

Permalänk
Medlem
Skrivet av vaasques:

@noyce: Jag hade klantat mig med kodblocken, fick allt att fungera nu

bara så att jag fattar det hela rätt nu:

string msg = input i form av string variabel. fråga här, double går ju in i metoden hur kommer det sig?
eftersom double fahrenheit = InputCatchTry("Skriv in temperratur i fahrenheit: ")

"static double" = den typ av variabel som metodens ouput stödjer.

public static double InputCatchTry(string msg= null)
(string msg= null) att strängen saknar något värde.

OM (msg inte är lika med null)
alltså - om string inte saknar värde vilket kan vara vilken input som helst från tangentbord --> skicka vidare till nästa bit kod

förstår jag det rätt eller har jag missuppfattat?
//vaasques

Double går inte "in i metoden", eftersom InputCatchTry retunerar en double, så kommer "double fahrenheit" bli en double. Det enda du kan skicka in är en string, alternativt null. Testa att skicka in olika värden i funktionen så ser du vad som går och inte går.

Varför jag valde att skicka in en string i metoden var för att du skrev olika meddelande beroende på vilket värde användaren skrev in från tangenbordet, blev smidigt att bara skicka med meddelandet direkt i funktionen. Sedan skrev jag dit hela null biten med tanken att du kanske ville använda funktionen utan att få en tom rad utskriven i consolefönstret.

Så om string är null, hoppa över att skriva ut något, annars skriv ut det.

Permalänk
Medlem
Skrivet av Tea42BBS:

IMHO så använder man try catch för "oväntade" fel. Att hantera heltal eller ej i detta program är inte oväntat och skall hanteras via t.ex. tryparse eller convert i en IF slinga.

Try catch är bra, men skall användas på rätt sett, inte som en villkors-styrning

// LZ

Hehe bästa jag någonsin sett var i ett legacysystem där dom hade målat in sig i ett hörn och någon hade skapat en "SucccessfulException" som dom kastade när allt gick korrekt för att kunna returnera ut via rätt väg