Ce face strtol și strtod
strtol citește un număr întreg ca atoi, dar prin al doilea argument îți spune unde s-a oprit: *sfarsit arată primul caracter necitit. Dacă sfarsit == s, nu a fost citită nicio cifră. Dacă *sfarsit != '\0', după număr a mai rămas text.
Al treilea argument este baza: 10 pentru zecimal, 16 pentru hexazecimal, 2 pentru binar, sau 0 ca funcția să recunoască singură prefixele 0x și 0.
Dacă numărul nu încape în long, funcția întoarce LONG_MAX sau LONG_MIN și setează errno la ERANGE. De aceea pui errno = 0 înainte de apel. strtod funcționează la fel pentru double. Există și strtoll, strtoul, strtof.
Parametri
| Parametru | Descriere |
|---|---|
s |
Textul de convertit. |
sfarsit |
Adresa unui char * în care se pune poziția unde s-a oprit citirea; poate fi NULL. |
baza |
Baza de numerație (2–36) sau 0 pentru detectare automată. |
Ce returnează
Valoarea citită; 0 dacă nu s-a citit nimic; LONG_MAX/LONG_MIN la depășire (cu errno = ERANGE).
Exemple
Exemplul 1: Validarea unei note
O funcție care acceptă doar un număr întreg complet, între 1 și 10.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
static bool citeste_nota(const char *text, int *nota) {
char *sfarsit;
errno = 0;
long valoare = strtol(text, &sfarsit, 10);
if (sfarsit == text || *sfarsit != '\0' || errno == ERANGE || valoare < 1 || valoare > 10) {
return false;
}
*nota = (int)valoare;
return true;
}
int main(void) {
const char *intrari[] = {"9", "10", "9a", "", "11", "99999999999999999999"};
for (size_t i = 0; i < 6; i++) {
int nota;
if (citeste_nota(intrari[i], ¬a)) {
printf("\"%s\" -> nota %d\n", intrari[i], nota);
} else {
printf("\"%s\" -> invalid\n", intrari[i]);
}
}
return 0;
}
Rezultat
"9" -> nota 9
"10" -> nota 10
"9a" -> invalid
"" -> invalid
"11" -> invalid
"99999999999999999999" -> invalid
Exemplul 2: Alte baze de numerație
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("%ld\n", strtol("ff", nullptr, 16));
printf("%ld\n", strtol("0x1A", nullptr, 0));
printf("%ld\n", strtol("1011", nullptr, 2));
printf("%ld\n", strtol("0755", nullptr, 0));
return 0;
}
Rezultat
255
26
11
493
Exemplul 3: Mai multe numere dintr-o linie cu strtod
Fiecare apel continuă de unde s-a oprit cel precedent, prin pointerul sfarsit.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *preturi = "12.50 3.99 101.2";
const char *p = preturi;
char *sfarsit;
double total = 0;
for (double v = strtod(p, &sfarsit); sfarsit != p; v = strtod(p, &sfarsit)) {
total += v;
p = sfarsit;
}
printf("Total: %.2f lei\n", total);
return 0;
}
Rezultat
Total: 117.69 lei
Greșeli frecvente
- Nu verifici
sfarsit: fără el,strtolnu este mai sigur decâtatoi. - Verifici
errnofără să-l fi pus pe 0 înainte; poate avea o valoare rămasă de la alt apel. - Treci rezultatul direct într-un
int:longpoate fi mai mare decâtint(pe sisteme de 64 de biți, Linux și macOS). Verifică limitele înainte de conversie.
Comenzi înrudite
atoi, atol și atof: Transformă rapid textul de la începutul unui șir într-un număr, fără să semnaleze erori.errno, perror și strerror: errno păstrează codul ultimei erori a unei funcții de bibliotecă; perror și strerror îl transformă într-un mesaj citibil.scanf: Citește valori de la tastatură după un șablon (%d, %lf, %s) și le scrie la adresele primite; returnează câte valori a citit.stdint.h și limits.h: Tipuri întregi cu dimensiune exactă (int32_t, uint8_t) și constantele cu valorile minime și maxime ale tipurilor (INT_MAX).fgets: Citește un rând întreg (cu tot cu spații) într-un tablou de caractere, fără să depășească dimensiunea dată.