Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: system() komennosta

vesikuusi [20.02.2011 21:36:03]

#

Olen usein netissä nähnyt ihmisten valittavan siitä, kun ihmiset käyttävät system()-komentoa konsoliohjelmissa. Sanovat sen jättävän tietoturva-aukkoja ja tekevän ohjelmasta riippuvaisen tiettyyn systeemiin. Ja tämän tiedän kyllä olevan totta, mutta sitä vaan mietin, että miten helv...krhm..kummassa nämä "mestariohjelmoijat" korvaavat esimerkiksi system("clear") tai winukalla system("cls") komennon? Siis muuten kuin lukemattomilla rivinvaihdiolla? Joo ja olen googlannut jo asiaa...

Tässä eräs esimerkki:
http://cboard.cprogramming.com/cplusplus-programming/49662-how-system-pause-cplusplus.html

Blaze [20.02.2011 21:50:04]

#

vesikuusi kirjoitti:

miten helv...krhm..kummassa nämä "mestariohjelmoijat" korvaavat esimerkiksi system("clear") tai winukalla system("cls") komennon?

Enpäs itseasiassa tiiä. Ei oo tullu koskaan tarvetta tuommoselle toiminnolle.

eq [20.02.2011 21:59:26]

#

Mitään alustariippumatonta tapaa "tyhjentää päätettä" ei ole; C- ja C++-standardeissa 'pääte' määritellään varsin löyhästi, eikä sitä varsinaisesti edes edellytetä.

Usein tämän tyhjennyksen voi yksinkertaisesti jättää pois - yksinään sillä ei CLI-ohjelmassa ihmeitä tehdä. Jos tarvitset enemmän kontrollia näkymään, käytä ncursesia (tämäkin on, luonnollisesti, alustariippuvainen, mutta saatavilla monille alustoille, ja tarjoaa selviä etuja tätä rajoitetta vastaan).

vesikuusi [20.02.2011 22:01:33]

#

kiitosta vaan :) pitääkin opiskella tuosta ncursesista...

Metabolix [20.02.2011 22:06:13]

#

Ruudun tyhjennykseen ei ole mitään C++:n omaa tapaa, koska C++ kielenä ei edellytä sellaista asiaa kuin "ruutu". Voisi oikeastaan sanoa, että jos ruudun tyhjentäminen on tarpeen, C++:n standardikirjasto on jo lähtökohtaisesti väärä väline. Edistyneempään ruudunkäsittelyyn on erilaisia kirjastoja, esimerkiksi curses (ncurses, PDCurses), josta on myös Ohjelmointiputkassa opas.

Toisena esimerkkinä antamasi pause on helppo toteuttaa aivan riittävässä määrin myös C++:lla yksinkertaisesti lukemalla ignore-funktiolla ylimääräinen rivi käyttäjältä. Jos ohjelmassa on jo aiemmin luettu tietoa, pitää ensin varmistaa, ettei edellisen rivin lopettava rivinvaihto ole jäänyt puskuriin. Tämä varmistaminen tapahtuu samaisella ignorella sen edellisen lukemisen yhteydessä.

#include <iostream>
#include <limits>

void rivi() {
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

int main() {
  std::cout << "Anna luku: ";
  int x;
  std::cin >> x;
  // Käyttäjä syöttää "123\n", joten "\n" jää puskuriin odottamaan. Luetaan se:
  rivi();

  std::cout << "Annoit luvun " << x << "." << std::endl;
  std::cout << "Paina enter jatkaaksesi." << std::endl;
  rivi();
}

Edit. No kerrankin se -tossu- oli nopeampi. :)

Edit + 1. Edellä esittämäni rivi-funktion voisi toteuttaa näinkin (muokattu GCC:n std::endl-toteutuksesta):

#include <iostream>
#include <limits>

template<typename _CharT, typename _Traits>
inline std::basic_istream<_CharT, _Traits>&
endl(std::basic_istream<_CharT, _Traits>& __is)
{
  return __is.ignore(std::numeric_limits<std::streamsize>::max(), __is.widen('\n'));
}

int main() {
  std::cout << "Anna luku: ";
  int x;
  std::cin >> x >> endl;

  std::cout << "Annoit luvun " << x << "." << std::endl;
  std::cout << "Paina enter jatkaaksesi." << std::endl;
  std::cin >> endl;
}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta