Permalänk
Medlem

Fråga if-sats i C#

Jag har följande kod:

foreach (char c2 in drive) { /if ((c2 == 'F' || c2 == 'f') && (truck.direction.Equals('w') || truck.direction.Equals('W'))) { truck.startX++; Console.WriteLine("truck.startX i if-sats " + truck.startX); positionX++; }

drive är bara en sträng t.ex. "fff"

Jag vet att truck.direction är 'w'.

Ändå går kompilatorn inte in i if-satsen. Kan man inte skriva så?

Visa signatur

Chassi: Fractal Design Define C || Processor: Intel i7-8700K || Grafikkort: ASUS GeForce GTX 1080Ti ROG Strix Gaming || Moderkort: Gigabyte Z370 AORUS ULTRA WIFI || Minne: Corsair Vengeance LPX DDR4 3000MHz 32 Gb || Lagring: Samsung 860 EVO 1TB SSD || PSU: Seasonic Focus+ 850W 85+ GOLD PSU || Skärm:Samsung Odyssey G9 || Windows 10

Permalänk
Medlem

@Larsp777:

Är direction en char eller sträng?

Du har ett "/" före if.

Sätt en breakpoint vid if för att se värdena och hur koden evalueras.

Permalänk
Medlem

Något av det du skriver stämmer inte.
https://dotnetfiddle.net/zIK2p2

Visa signatur

Spela Swemantle! Du vet att du vill.

Ibland har jag fel, men då är det någon annans fel.

Permalänk
Medlem
Skrivet av Haladria:

@Larsp777:

Är direction en char eller sträng?

Du har ett "/" före if.

Sätt en breakpoint vid if för att se värdena och hur koden evalueras.

Strecket vid if var bara ett misstag när jag postade koden.

drive är en sträng som jag plockar tecken ur.

Visa signatur

Chassi: Fractal Design Define C || Processor: Intel i7-8700K || Grafikkort: ASUS GeForce GTX 1080Ti ROG Strix Gaming || Moderkort: Gigabyte Z370 AORUS ULTRA WIFI || Minne: Corsair Vengeance LPX DDR4 3000MHz 32 Gb || Lagring: Samsung 860 EVO 1TB SSD || PSU: Seasonic Focus+ 850W 85+ GOLD PSU || Skärm:Samsung Odyssey G9 || Windows 10

Permalänk
Medlem

truck.direction.Equals('w')

Du jämför direction med en char, stämmer det? Jag skulle nog inte använda Equals i detta fall, utan likhetstecken för att säkerställa typningen. Equals har en overload av typen Object så det är lätt hänt att man man hamnar i ett sånt här scenario där koden kompilerar men aldrig kommer fungera.

Ett generellt sett bättre tips är att försöka lära sig hur debuggern i utvecklingsmiljön fungerar. Den är ett ovärderligt verktyg som kommer spara mycket tid och frustration.

https://docs.microsoft.com/en-us/visualstudio/debugger/debugg...

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av planders:

truck.direction.Equals('w')

Du jämför direction med en char, stämmer det? Jag skulle nog inte använda Equals i detta fall, utan likhetstecken för att säkerställa typningen. Equals har en overload av typen Object så det är lätt hänt att man man hamnar i ett sånt här scenario där koden kompilerar men aldrig kommer fungera.

Går utmärkt att använda Equals om båda du jämför med är av typen char.
'A'.Equals('A') // True

Tips vid jämförelse är dock att sätta t.ex. .ToLower() / ToUpper() på char/string du jämför med så att du slipper skriva == w och == W.

Jämför du strängar är det också ett alternativ att skriva string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase );

TS:
Programmet komplierar men går alltså förbi if-satsen? Sätt en breakpointen vid loopen och iterera igenom med F11, kolla vad du har för värden på dina variabler. Testar jag koden med hårdkodad data som du beskrev "ffff" och att truck direction är 'W' så går du in i if-satsen.

Permalänk
Medlem
Skrivet av zaibuf:

Går utmärkt att använda Equals om båda du jämför med är av typen char.
'A'.Equals('A') // True

Tips vid jämförelse är dock att sätta t.ex. .ToLower() / ToUpper() på char/string du jämför med så att du slipper skriva == w och == W.

Jämför du strängar är det också ett alternativ att skriva string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase );

Självklart går det bra om båda objekten är av samma typ. Min poäng är att det är en farlig metod eftersom den kan ge oväntade resultat utan förvarning.

Till exempel om direction byter typ till int skulle programmet fortfarande kompilera men antagligen inte ge det svar man väntat sig. Om man har otur tar det även lång tid att felsöka en sån bugg.

Skickades från m.sweclockers.com

Permalänk
Medlem

@Larsp777: Är truck.direction en char eller en string?
Har du skrivit typ:

public struct Truck { public char direction; }

eller

public struct Truck { public string direction; }

eller

public struct Truck { public dynamic direction; }

Samt

Har du skrivit initiering i koden ovan som vi inte heller ser typ

truck.direction = 'w'; (char)

eller

truck.direction = "w"; (string)

Verkar som att if-satsen evaluerar för char med du skickar in en string kanske?
Om du kör [public dynamic direction;] så blir det en string med dubbel citat "s" och char med enkel citat 'c'

Personligen rekommenderar jag att undvika att köra dynamic om det inte verkligen behövs, min åsikt. Bara användas när det kan verkligen hjälpa dig och det "normala" alternativet skulle vara mer komplext.

Permalänk
Medlem

Här är där jag initierar truck.direction.

Jag tror att problemet är där.

Just nu är truck.direction en char. Men får att man inte kan omvandla string till char.

int n = 0; int roomXmax = 8; int roomYmax = 8; MonsterTruck truck = new MonsterTruck(); Console.WriteLine("Skriv in X och Y värde för starposition av bil. Skriv även riktning på bil. (N = norr, S = syd, W = väst och E = öst) "); Console.WriteLine("Separera med mellanslag "); string carValues = Console.ReadLine(); string[] letters2 = carValues.Split(' '); foreach (var c2 in letters2) { n++; if (n == 1) truck.startX = Convert.ToInt32(c2); if (n == 2) truck.startY = Convert.ToInt32(c2); if (n == 3) { truck.direction = c2; //Problemet är här } } Console.WriteLine("X-värde: " + truck.startX); Console.WriteLine("Y-värde: " + truck.startY); Console.WriteLine("Riktning: " + truck.direction); Console.ReadLine();

Visa signatur

Chassi: Fractal Design Define C || Processor: Intel i7-8700K || Grafikkort: ASUS GeForce GTX 1080Ti ROG Strix Gaming || Moderkort: Gigabyte Z370 AORUS ULTRA WIFI || Minne: Corsair Vengeance LPX DDR4 3000MHz 32 Gb || Lagring: Samsung 860 EVO 1TB SSD || PSU: Seasonic Focus+ 850W 85+ GOLD PSU || Skärm:Samsung Odyssey G9 || Windows 10

Permalänk
Medlem

c2 som du initierar truck.direction med är väl en string? titta på debuggern steg för steg.
Så helt enkelt är c2 string och i din if stats så frågar du efter char i c2. där ligger förmodligen felet.
När du använder var / dynamic så kan du få type fel / missmatch om du inte försäkrar dig det eller typecast:ar till en char.

Permalänk
Medlem

Måste direction vara en char? Enklare om den är string.

Ett tips är att skippa loopen och indexera letters2 istället.

Ex:

direction = letters2[2]; // Börjar på index 0

Skickades från m.sweclockers.com

Permalänk
Medlem

Jag löste det men fick nytt problem.

Ska göra en applikation som simulerar en bil.

Man sätter först hur stort rummet ska vara.

Sedan var bilen är i rummet och vilken riktning den har.

Sedan ska man skriva in hur den kör. T.ex. fflbff där f är framåt, b bakåt, l vänster och r höger.

Om man skriver höger eller vänster ska man inte köra fram eller bak, bara byta riktning.

Det fungerar ok men när bilen ska köra går den in en if-sats den inte borde.

Provade med FFLFFB

När värdet på c2 är L borde den inte gå in här, men gör det:

if ((c2 == 'B' || c2 == 'b') && truck.direction.Equals('n') || truck.direction.Equals('N') && turn == false) { truck.startY--; }

Här är hela koden:

MonsterTruck truck = new MonsterTruck(); bool input = false; bool input2 = false; bool input3 = false; int roomX = 0; int roomY = 0; int roomXmax = 0; int roomYmax = 0; int positionX = 0; int positionY = 0; int j = 0; int k = 0; int n = 0; bool turn = false; //******************************* Mata in värden för rum ****************************** while (!input) { try { input = true; Console.WriteLine("Skriv in X och Y värde för rummet, separera med mellanslag"); string roomValues = Console.ReadLine(); Match m = Regex.Match(roomValues, @\d{1} \d{1}); if (!m.Success) throw new FormatException("Fel värden"); string[] letters = roomValues.Split(' '); foreach (var c in letters) { j++; if (j == 1) roomXmax = Convert.ToInt32(c); if (j == 2) roomYmax = Convert.ToInt32(c); } } catch (FormatException e) { Console.WriteLine(e); Console.WriteLine("Fel inmatning, försök igen"); input = false; } catch (ArgumentNullException e) { Console.WriteLine(e); Console.WriteLine("Fel inmatning, försök igen"); input = false; } } Console.WriteLine("X-värde: " + roomXmax); Console.WriteLine("Y-värde: " + roomYmax); //********************************** Mata in värden för bil ******************************************** while (!input2) { try { input2 = true; Console.WriteLine("Skriv in X och Y värde för starposition av bil. Skriv även riktning på bil. (N = norr, S = syd, W = väst och E = öst) "); Console.WriteLine("Separera med mellanslag "); Console.WriteLine("Maxvärde för X är " + roomXmax + " och för Y " + roomYmax); string carValues = Console.ReadLine(); Match m2 = Regex.Match(carValues, @\d{1} \d{1} [WENSwens]); if (!m2.Success) throw new FormatException("Fel värden"); string[] letters2 = carValues.Split(' '); foreach (var c2 in letters2) { //char input1 = char.Parse(c2); //Console.WriteLine("Variabel för bil: " + input1); n++; if (n == 1) truck.startX = Convert.ToInt32(c2); if(truck.startX > roomXmax) throw new FormatException("För högt X värde för bil"); if (n == 2) truck.startY = Convert.ToInt32(c2); if (truck.startY > roomYmax) throw new FormatException("För högt y värde för bil"); if (n == 3) { truck.direction = Convert.ToChar(c2); } } } catch (FormatException e) { Console.WriteLine(e); Console.WriteLine("Fel inmatning, försök igen"); input2 = false; } catch (ArgumentNullException e) { Console.WriteLine(e); Console.WriteLine("Fel inmatning, försök igen"); input2 = false; } } Console.WriteLine("X-värde: " + truck.startX); Console.WriteLine("Y-värde: " + truck.startY); Console.WriteLine("Riktning: " + truck.direction); //********************************** Kör simulation ******************************************** while (!input3) { try { input3 = true; Console.WriteLine("Skriv in hur bilen ska köra. Möjliga värden är: (F = framåt, B = back, W = vänster och E = höger) "); Console.WriteLine("Separera med mellanslag "); string drive = Console.ReadLine(); Match m3 = Regex.Match(drive, @[FBLRfblr]); if (!m3.Success) throw new FormatException("Fel värden"); foreach (char c2 in drive) { Console.WriteLine("c2: " + c2); // Console.WriteLine("Truck.direction: " + truck.direction); // if (truck.startX > 0 || truck.startY > 0 || positionY <= roomXmax || positionX <= roomYmax) //{ turn = false; if ((c2 == 'F' || c2 == 'f') && (truck.direction.Equals('w') || truck.direction.Equals('W'))) { truck.startX++; } if ((c2 == 'B' || c2 == 'b') && truck.direction.Equals('w') || truck.direction.Equals('W')) { truck.startX--; } if ((c2 == 'L' || c2 == 'l') && truck.direction.Equals('w') || truck.direction.Equals('W')) { truck.direction = 'N'; turn = true; } if ((c2 == 'R' || c2 == 'r') && truck.direction.Equals('w') || truck.direction.Equals('W')) { truck.direction = 'S'; } if ((c2 == 'F' || c2 == 'f') && (truck.direction.Equals('n') || truck.direction.Equals('N')) && turn == false) { truck.startY++; } if ((c2 == 'B' || c2 == 'b') && truck.direction.Equals('n') || truck.direction.Equals('N') && turn == false) { truck.startY--; } if ((c2 == 'L' || c2 == 'l') && truck.direction.Equals('n') || truck.direction.Equals('N') && turn == false) { truck.direction = 'E'; } if ((c2 == 'R' || c2 == 'r') && truck.direction.Equals('n') || truck.direction.Equals('N') && turn == false) { truck.direction = 'W'; } //} //else // Console.WriteLine("Du har kraschat!"); Console.WriteLine("Bilens X-värde: " + truck.startX); Console.WriteLine("Bilens Y-värde: " + truck.startY); Console.WriteLine("Truck.direction: " + truck.direction); } } catch (FormatException e) { Console.WriteLine(e); Console.WriteLine("Fel inmatning, försök igen"); input2 = false; } catch (ArgumentNullException e) { Console.WriteLine(e); Console.WriteLine("Fel inmatning, försök igen"); input2 = false; } } Console.ReadLine();

Visa signatur

Chassi: Fractal Design Define C || Processor: Intel i7-8700K || Grafikkort: ASUS GeForce GTX 1080Ti ROG Strix Gaming || Moderkort: Gigabyte Z370 AORUS ULTRA WIFI || Minne: Corsair Vengeance LPX DDR4 3000MHz 32 Gb || Lagring: Samsung 860 EVO 1TB SSD || PSU: Seasonic Focus+ 850W 85+ GOLD PSU || Skärm:Samsung Odyssey G9 || Windows 10

Permalänk
Medlem

@Larsp777: && har högre prioritet än || i C# (och de flesta andra språk). Som du skrivit ditt villkor så kommer det alltså vara sant när c2 är 'b' eller 'B' och truck.direction är 'n', eller när truck.direction är 'N' och turn är false. Du vill troligtvis ha parenteser runt truck.direction-jämförelserna för att villkoret ska bli som du vill.

Du kan förresten använda Char.ToUpper för att göra om användarens inmatning till en versal, så slipper du hålla på och jämföra varje variabel två gånger överallt.

Permalänk
Medlem
Skrivet av perost:

@Larsp777: && har högre prioritet än || i C# (och de flesta andra språk). Som du skrivit ditt villkor så kommer det alltså vara sant när c2 är 'b' eller 'B' och truck.direction är 'n', eller när truck.direction är 'N' och turn är false. Du vill troligtvis ha parenteser runt truck.direction-jämförelserna för att villkoret ska bli som du vill.

Du kan förresten använda Char.ToUpper för att göra om användarens inmatning till en versal, så slipper du hålla på och jämföra varje variabel två gånger överallt.

Ok, ska kolla på det, tackar!

Visa signatur

Chassi: Fractal Design Define C || Processor: Intel i7-8700K || Grafikkort: ASUS GeForce GTX 1080Ti ROG Strix Gaming || Moderkort: Gigabyte Z370 AORUS ULTRA WIFI || Minne: Corsair Vengeance LPX DDR4 3000MHz 32 Gb || Lagring: Samsung 860 EVO 1TB SSD || PSU: Seasonic Focus+ 850W 85+ GOLD PSU || Skärm:Samsung Odyssey G9 || Windows 10