Üdv!
Lassan két órás keresgélés töprengés után, szeretném valakinek a segítségét kérni a következő problémámval...(gondolom igen egyszerű a megoldása)
Az inputstreamből szeretnék adatot beolvasni, majd int-té konvertálni, a gondom viszont az, hogy overflownál kivételt kéne dobnom amire eleddig nem jöttem rá, hogyan kell, mármint hogy dönthetem el, hogy volt-e.
Előre is köszi a segítséget...
- 1869 megtekintés
Hozzászólások
pont akkora mennyiséget olvass be, mint amekorra egy int:)
- A hozzászóláshoz be kell jelentkezni
Kicsit bővebben lehetne, mert kezdő vagyok...
- A hozzászóláshoz be kell jelentkezni
egészen konkrétan mit is szeretnél? (beolvasni inputstream-ről ez eléggé kevéske infó). Billentyűzetről beolvasni egy számot, vagy socketről, filebol, stb.
- A hozzászóláshoz be kell jelentkezni
Ha jól értem: input stream -> char buffer (pl: scanf), char buffer -> integer (pl: atoi). Az atoi nem végez hibakezelést. http://linux.die.net/man/3/atoi
Ha csak ennyi a problémád, ezernyi megoldás van.
Egyébként másold be a kódot, úgy könnyebb megérteni mit is szeretnél. :)
- A hozzászóláshoz be kell jelentkezni
int ReadNat(std::string msg, std::string errormsg )
{
int n;
bool hiba;
do{
std::cout << msg;
std::string str;
std::cin >> str;
n = atoi(str.c_str());
hiba = (n==0 && str!="0") || n<0;
if(hiba) std::cout<< errormsg << std::endl;
}while(hiba);
return n;
}
- A hozzászóláshoz be kell jelentkezni
Először is, ha 'n' nem lehet negatív, akkor legyen már unsigned int. Másodszor pedig leírtam az előbb a megoldást. Az atoi() nem kezel hibát, de például az strtol() már igen. Vagy dobj össze gyorsan egy konvertáló függvényt, ott azt kezelsz le amit csak akarsz.
- A hozzászóláshoz be kell jelentkezni
köszi, segítségeket, probléma megoldva....
- A hozzászóláshoz be kell jelentkezni
Bár azt írtad, hogy probléma megoldva, azért hadd szóljak még hozzá, mert a kérdés az egyik kedvenc vesszőparipám :)
Először is azt javasolnám, hogy ne keverd a C-s és C++-os módszert. A C++ nem C. Igen, persze, "elérhető" benne a C; azonban annyira más a stílusuk, hogy nagyon nem hasznos a kettőt vegyíteni. Én legalábbis éles határt vonnék itt a (userspace) libc függvények és a syscall-ok között. Nyilván syscall-ok helyett nem tudsz mit használni (amelyek a man 2. fejezetében vannak), a man 3. fejezete helyett viszont használj tisztán C++-t.
Ennyi üres locsogás után nézzünk konkrétumot, bővebben lásd pl. innen indulva:
#include <iostream>
using namespace std;
int
main()
{
int i;
// manual check
cin.clear();
cin >> i;
if (!cin.good()) {
cerr << "failure detected in manual check\n";
return 1;
}
// with exceptions -- clear control state before setting up exception mask
// so that no exception is thrown immediately
cin.clear();
cin.exceptions(istream::eofbit | istream::failbit | istream::badbit);
try {
cin >> i;
}
catch (ios_base::failure& e) {
cerr << "failure detected via exception\n";
return 1;
}
}
Első hiba:
2147483648
failure detected in manual check
Második hiba:
2147483647
2147483648
failure detected via exception
C-ben a következő függvényhez hasonlót szeretek használni (lásd strtol()):
#define _XOPEN_SOURCE 600
#include <stdlib.h> /* strtol() */
#include <errno.h> /* errno */
#include <limits.h> /* INT_MIN */
#include <stdio.h> /* fprintf() */
static int
long_parse(long *dest, const char *src, long min, long max)
{
char *endptr;
errno = 0;
*dest = strtol(src, &endptr, 10);
return ('\0' != *src && '\0' == *endptr && 0 == errno
&& min <= *dest && *dest <= max) ? 0 : -1;
}
int
main(int argc, char **argv)
{
while (0 != *++argv) {
long tmp;
if (-1 == long_parse(&tmp, *argv, INT_MIN, INT_MAX)) {
(void)fprintf(stderr, "unable to parse \"%s\" as an int\n", *argv);
}
else {
int i;
i = tmp;
(void)fprintf(stdout, "\"%s\" parsed as int %d\n", *argv, i);
}
}
return EXIT_SUCCESS;
}
Futtatva:
$ ./proba2 \
'' \
' ' \
'1 ' \
' 1' \
a \
9223372036854775808 \
2147483648 \
2147483647 \
-2147483648 \
-2147483649
unable to parse "" as an int
unable to parse " " as an int
unable to parse "1 " as an int
" 1" parsed as int 1
unable to parse "a" as an int
unable to parse "9223372036854775808" as an int
unable to parse "2147483648" as an int
"2147483647" parsed as int 2147483647
"-2147483648" parsed as int -2147483648
unable to parse "-2147483649" as an int
Nézzük, mit melyik részfeltétel nem teljesüléséért utasított el (miért úgy néz ki a
long_parse()
, ahogy):
-
"a"
: a "subject sequence" (ld. fenti linket) üres, ezért nincs konverzió. Ekkor a visszaadott érték 0, az
endptr
a sztring elejére mutat, az
errno
-nak viszont nem kötelező
EINVAL
-t felvennie. Így ezt az esetet a
'\0' == *endptr
részfeltétel fogja meg.
-
" "
: ugyanaz az eset, mint
"a"
, lásd fent.
-
""
: ugyanaz az eset, mint
"a"
, lásd fent, azzal a csúnya kiegészítéssel, hogy a sztring eleje, ahova az
endptr
mutat, egyből a vége is, ezért ezt a
'\0' != *src
fogja meg.
-
"1 "
:
'\0' == *endptr
-
"9223372036854775808"
:
0 == errno
-
"2147483648"
:
*dest <= max
-
"-2147483649"
:
min <= *dest
Miért kell az
errno = 0;
az egész elé: ha az
strtol()
nem állítja be -- lásd például sikeres parse-olásnál -- valamilyen értékre az
errno
-t, akkor az értékadás nélkül az
errno
értéke a
0 == errno
vizsgálatban meghatározatlan lehetne.
- A hozzászóláshoz be kell jelentkezni
Annak a #define-nak van bármiféle jelentősége a C-ben? :)
Amúgy teljesen igazad van a C és a C++ elválasztásában, sajnos én is szeretek C++ kódba C-t illeszteni, ami nem szép, de néha egyszerűbb. :(
- A hozzászóláshoz be kell jelentkezni
Van, bizonyos fuggvenyek egy icipicit maskepp mukodnek ennek a valtozonak a beallitasa eseten.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Annak a #define-nak van bármiféle jelentősége a C-ben? :)
- A hozzászóláshoz be kell jelentkezni
Ez a long_parse azert is jo, mert a strtol ele be lehet lokdosni olyasmiket is, hogy peldaul a whitespace karaktereket porgesse ki a sztringbol, igy parsolhatova valnak olyan stringek is, amik alapbol nem (pl a " 1" es a "1 " is).
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni