Skocz do zawartości

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

RIP

C# - Jak wstrzymać wykonywanie kodu

Polecane posty

Chodzi oczywiście o znaną bolączkę Visual Studio, czyli konieczność używania metod takich jak cin.get() w przypadku C++, czy różnych Console.Read...() w C#. O ile w przypadku C++ problem rozwiązało głównie to, że używałem Code::Blocks, które takich operacji nie wymaga, o tyle w C# mam problem, bo nie wygląda to do końca tak, jakbym chciał. W spoilerze zamieszczę kod do swojego w zasadzie pierwszego programiku w C#. Tak dla zobrazowania, bo wcale potrzebna nie będzie. Chodzi mi po prostu o to, czy da się zrobić tak, by po wprowadzeniu do wejścia jakiejś zmiennej i potwierdzeniu enterem pojawiała się prośba o kolejną zmienną i czekała na nią. Obecnie, gdybym np. w poniższym kodzie nie użył "Console.ReadKey() po prośbie o stawkę, program wyświetliłby od razu prośbę o wartość premii i wywalił błąd o nieprawidłowych formacie danych wejściowych. Z ReadKey() z kolei muszę wcisnąć dodatkowy Enter, żeby w ogóle pojawiła się ta prośba. A ja nie chcę co fragment wciskać dodatkowego Entera w celu wyświetlenia kolejnych instrukcji. Niewygodne to i idzie się zamotać. W C++ i Code::Blocks wystarczyło na zmianę używać cout <<, cin>> bez żadnych dodatkowych linijek i program ładnie przechodził dalej.

Aha...i powiedzcie mi, dlaczego w jednym przypadku wystarczy mi ReadKey(), a przy podawaniu na wejściu zmiennej char ch już muszę użyć ReadLine(), by przy następnym wejściu nie wywaliło mi błedu formatu?

Czy koniecznie trzeba używać tych konwersji na typ int, czy double? Nie ma jakiejś metody jak std::cin z C++, która sama wszystko załatwi niezależnie od typu wprowadzanej zmiennej?

Tutaj "program" w C#


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace wypłata
{
class Program
{
static void Main(string[] args)
{
ConsoleColor kolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Program obliczający wypłatę pracownika");
Console.ForegroundColor = kolor;
Console.Write("Podaj stawkę godzinową pracownika: ");
int s = int.Parse(Console.ReadLine());
Console.ReadKey();
Console.Write("Podaj wysokość premii: ");
int p = int.Parse(Console.ReadLine());
Console.ReadLine();
Worker First = new Worker(s, p);
Menu();
char ch = (char)Console.Read();
Console.ReadLine();
while (char.IsLetter(ch) && char.ToUpper(ch) != 'K')
{
switch (ch)
{
case 'P':
case 'p':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double normalki = double.Parse(Console.ReadLine());
Console.ReadKey();
First.Dzien(normalki);
break;
case 'O':
case 'o':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double nocne = double.Parse(Console.ReadLine());
Console.ReadKey();
First.Nocka(nocne);
break;
case 'N':
case 'n':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double niedzielne = double.Parse(Console.ReadLine());
Console.ReadKey(); First.Niedziela(niedzielne);
break;
case 'S':
case 's':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double sobotnie = double.Parse(Console.ReadLine());
Console.ReadKey();
First.Sobota(sobotnie);
break;
default:
Console.WriteLine("Podaj prawidłową wartość!");
Console.WriteLine();
break;
}
Menu();
ch = (char)Console.Read();
Console.ReadLine();
}
Console.WriteLine();
Console.WriteLine();
First.Show();
Console.WriteLine("Dziękuję za skorzystanie z programu. Aby zakończyć, wciśnij dowolny klawisz...");
Console.ReadKey();
}
static void Menu()
{
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Wciśnij P, jeśli dzień powszedni");
Console.WriteLine("Wciśnij S, jeśli sobota");
Console.WriteLine("Wciśnij N, jeśli niedziela");
Console.WriteLine("Wciśnij O, jeśli nocka");
Console.WriteLine("Wciśnij K, aby zakończyć wprowadzanie godzin i zobaczyć przewidywaną WYPŁATĘ!");
}
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace wypłata
{
class Worker
{
const int Dniowka = 8;
private int Stawka;
private double Normalne;
private double Nadgodziny;
private double Setki;
private double Wszystkie;
private double Premia;
private double Wypłata;
public Worker() { }
public Worker(int stawka, int premia)
{
Stawka = stawka;
Premia = premia;
Normalne = 0;
Nadgodziny = 0;
Setki = 0;
Wszystkie = 0;
Wypłata = premia;
}
public void Dzien(double godziny)
{
if (godziny <= Dniowka)
{
Normalne += godziny;
Wszystkie += godziny;
Wypłata += (godziny * Stawka);
}
else
{
Normalne += Dniowka;
Nadgodziny += godziny - Dniowka;
Wszystkie += godziny;
Wypłata += (Dniowka * Stawka) + ((godziny - Dniowka) * Stawka * 1.5);
}
}
public void Nocka(double godziny)
{
if (godziny <= Dniowka)
{
Normalne += godziny;
Wszystkie += godziny;
Wypłata += (godziny * Stawka);
}
else
{
Normalne += Dniowka;
Setki += godziny - Dniowka;
Wszystkie += godziny;
Wypłata += (Dniowka * Stawka) + ((godziny - Dniowka) * Stawka * 2);
}
}
public void Sobota(double godziny)
{
Nadgodziny += godziny;
Wszystkie += godziny;
Wypłata += godziny * Stawka * 1.5;
}
public void Niedziela(double godziny)
{
Setki += godziny;
Wszystkie += godziny;
Wypłata += godziny * Stawka * 2;
}
public void Show()
{
Console.WriteLine(@"Pracownik przepracował w tym miesiącu {0} godzin. W tym {1} normalnych, {2} ""50-tek"" ",
Wszystkie, Normalne, Nadgodziny);
Console.WriteLine(@"oraz {0} ""setek""", Setki);
Console.Write("Przy premii w wysokości {0} złotych daje to wypłatę w wysokości ", Premia);
ConsoleColor kolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("{0} złotych!", Wypłata);
Console.WriteLine();
Console.ForegroundColor = kolor;
}
}
}

a tutaj elegancko i bez pauz działający w C++ z C::B


#ifndef HEADER_H_
#define HEADER_H_
#include <iostream>
class Pracownik
{
double stawka;
int normalne;
int nadgodziny;
int setki;
int wszystkie;
double premia;
double wyplata;
public:
Pracownik();
void dzien(int godziny);
void sobota(int godziny);
void niedziela(int godziny);
void show() const;
};
#endif // HEADER_H_


#include "header.h"
const int DNIOWKA = 8;
Pracownik::Pracownik():stawka(0), normalne(0), nadgodziny(0), setki(0), wszystkie(0)
{
std::cout << "Podaj stawke godzinowa pracownika: ";
std::cin >> stawka;
std::cout << "I wysokosc premii: ";
std::cin >> premia;
wyplata = premia;
}
void Pracownik::dzien(int godziny)
{
if (godziny <= DNIOWKA)
{normalne += godziny;
wszystkie += godziny;
wyplata += stawka * godziny;}
else if (godziny > DNIOWKA)
{
normalne += DNIOWKA;
nadgodziny += godziny - DNIOWKA;
wszystkie += godziny;
wyplata += (stawka * DNIOWKA) + (stawka * 1.5 * (godziny - DNIOWKA));
}
else if (godziny < 1)
std::cout << "Ilosc przepracowanych godzin nie moze byc ujema";
}
void Pracownik::sobota(int godziny)
{
nadgodziny += godziny;
wszystkie += godziny;
wyplata += stawka * 1.5 * godziny;
}
void Pracownik::niedziela(int godziny)
{
setki += godziny;
wszystkie += godziny;
wyplata += stawka * 2 * godziny;
}
void Pracownik::show() const
{
std::cout << "\nPracownik przepracowal w tym miesiacu " << wszystkie << " godzin. W tym:\n"
<< normalne << " normalnych, \n" << nadgodziny << " nagodzin,\n" << setki << " setek.\n"
<< "Przy stawce: " << stawka << "zl na godzine i premii w wyskosci: " << premia << "zl\notrzyma wyplate"
<< " w wysokosci " << wyplata << " zl.";
}


#include "header.h"
#include <cctype>
void showmenu();
int main()
{
std::cout << "PROGRAM OBLICZAJACY WYSOKOSC WYPLATY PRACOWNIKA\n";
Pracownik Pierwszy;
char ch;
showmenu();
std::cin >> ch;
while (isalpha(ch) && toupper(ch) != 'K')
{
switch(ch)
{
case 'P':
case 'p':
int normalne;
std::cout << "Ile godzin pracowal pracownik tego dnia?: ";
std::cin >> normalne;
Pierwszy.dzien(normalne);
break;
case 'S':
case 's':
int soboty;
std::cout << "Ile godzin pracowal pracownik tego dnia?: ";
std::cin >> soboty;
Pierwszy.sobota(soboty);
break;
case 'N':
case 'n':
int niedziele;
std::cout << "Ile godzin pracowal pracownik tego dnia?: ";
std::cin >> niedziele;
Pierwszy.niedziela(niedziele);
break;
default :
std::cout << "Nie ma takiej opcji! Sprobuj ponownie.\n";
}
showmenu();
std::cin >> ch;
}
std::cout << "\nDziekuje za wspolprace! Oto wyniki:\n\n";
Pierwszy.show();
char k;
std::cout << "\n\nAby zakonczyc dzialanie programu wcisnij \"k\"";
while (std::cin >> k && toupper(k) != 'K')
std::cout << "Nieprawidlowy klawisz! Wcisnij k.\n";
return 0;
}
void showmenu()
{
std::cout << "\n\nWcisnij:\n";
std::cout << "P - Jesli dzien powszedni,\n";
std::cout << "S - Jesli sobota,\n";
std::cout << "N - Jesli niedziela,\n";
std::cout << "K - aby zakonczyc wprowadzanie godzin.\n";
}

PS. Domyślam się, że to niezbyt elegancko rozwiązanie zagadnienie, ale to już zostawmy smile_prosty.gif

Link do komentarza
Udostępnij na innych stronach

Trochę późno, ale dopiero teraz przeczytałem Twój temat. Zamiast Console.Read() możesz użyć właśnie Console.ReadKey() do pobrania wyboru menu bez konieczności wciskania entera. Obecne Console.ReadKey() wydają się zbędne. Console.ReadLine() IMO nadużywasz :-) Zobacz, u mnie działa:

static void Main(string[] args)
{
ConsoleColor kolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Program obliczający wypłatę pracownika");
Console.ForegroundColor = kolor;
Console.Write("Podaj stawkę godzinową pracownika: ");
int s = int.Parse(Console.ReadLine());
Console.Write("Podaj wysokość premii: ");
int p = int.Parse(Console.ReadLine());
Worker First = new Worker(s, p);
Menu();
char ch = (char)Console.ReadKey(true).KeyChar;
while (char.IsLetter(ch) && char.ToUpper(ch) != 'K')
{
switch (ch)
{
case 'P':
case 'p':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double normalki = double.Parse(Console.ReadLine());
First.Dzien(normalki);
break;
case 'O':
case 'o':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double nocne = double.Parse(Console.ReadLine());
First.Nocka(nocne);
break;
case 'N':
case 'n':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double niedzielne = double.Parse(Console.ReadLine());
First.Niedziela(niedzielne);
break;
case 'S':
case 's':
Console.Write("Ile godzin pracownik przepracował w tym dniu? ");
double sobotnie = double.Parse(Console.ReadLine());
First.Sobota(sobotnie);
break;
default:
Console.WriteLine("Podaj prawidłową wartość!");
Console.WriteLine();
break;
}
Menu();
ch = (char)Console.ReadKey(true).KeyChar;
}
Console.WriteLine();
Console.WriteLine();
First.Show();
Console.WriteLine("Dziękuję za skorzystanie z programu. Aby zakończyć, wciśnij dowolny klawisz...");
Console.ReadKey();
}

A jeśli chodzi o czytanie i parsowanie, to IMO tak jak jest, jest lepiej bo bezpieczniej - nigdy nie sypnie Ci się bo user wpisał tekst, a spodziewałeś się int. W tej chwili oczywiście Twoja aplikacja rzuci wyjątkiem, bo robisz ryzykowne typ.Parse. Zamiast tego lepiej zrobić typ.TryParse(stringIn, out typ wartosc) - TryParse zwraca bool informujący o poprawności parsowania. Albo możesz otoczyć switch blokiem try-catch i łapać błędy parsowania.

Link do komentarza
Udostępnij na innych stronach

O ja Cię:) No działa :) Teraz muszę sobie usiąść i ładnie przeanalizować to eleganckie rozwiązanie, bo dotychczas nie stworzyłem niczego, co od razu reaguje na wybór w switchu bez Entera nawet. Dziękuję bardzo, Wiesiu. A już traciłem nadzieję :)

Link do komentarza
Udostępnij na innych stronach



  • Kto przegląda   0 użytkowników

    • Brak zalogowanych użytkowników przeglądających tę stronę.
×
×
  • Utwórz nowe...