Funzione di conversione da alfanumerici a numerici - esempi in C

Tutti i linguaggi di programmazione hanno funzioni per convertire alfanumerici che rappresentano interi in interi.

Quando digitate sulla testiera la sequenza di caratteri '1' '2' e '3' questi vengono convertiti nella rispettiva codifica binaria in base alla tabella ad esempio ASCII. Quindi il carattere '1' verrà codificato in un byte con il valore binario di 49 decimale, il carattere '2' in un byte con il valore binario di 50 decimale e 3 in un byte con il valore binario di 51 decimale.

Quindi:

La sequenza 123 viene codificata in 3 byte 
uno per ogni carattere, in base alla codifica ASCII:

|   49|   50|   51|

in binario:

|00110001|00110010|00110011|

E' necessario per eseguire i calcoli è necessario convertire questa sequenza di caratteri nell'intero corrispondente. Tutti i linguaggi di programmazione hanno delle funzioni che permettono questa conversione, ad esempio in C la funzione atoi:

int atoi (const char * str);

Converte una sequenza di caratteri in un intero.

Un esempio di utilizzo:

/* atoi example */
#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atoi */

int main ()
{
  int i;
  char buffer[256];
  printf ("Enter a number: ");
  fgets (buffer, 256, stdin);
  i = atoi (buffer);
  printf ("The value entered is %d. Its double is %d.\n", i, i*2);
  return 0;
}

L'output:

Enter a number: 73
The value entered is 73. Its double is 146.

Può essere utile fare una nostra implementazione semplice della funzione atoi per capire come convertire una sequenza di caratteri che rappresentano un intero in una variabile di tipo intero.

Sotto una semplice implementazione:

// Program to implement atoi() in C
#include <stdio.h>

// A simple atoi() function
int myAtoi(char str[])
{
	// Initialize result
	int res = 0;

	// Iterate through all characters
	// of input string and update result
	// take ASCII character of corosponding digit and
	// subtract the code from '0' to get numerical
	// value and multiply res by 10 to shuffle
	// digits left to update running total
	for (int i = 0; str[i] != '\0'; ++i)
		res = res * 10 + str[i] - '0';

	// return result.
	return res;
}

// Driver Code
int main()
{
	char str[] = "89789";

	// Function call
	int val = myAtoi(str);
	printf("%d ", val);
	return 0;
}

Una implementazione un più controlli sull'input e che gestisca i negativi. Se il primo carattere è '-' allora setta il segno a negativo e converte il testo della sequenza di caratteri (stringa) come numero utilizzando l'approccio precedente e poi moltiplicando il risultato per il segno:

// A C program for
// implementation of atoi
#include <stdio.h>

// A simple atoi() function
int myAtoi(char str[])
{
	// Initialize result
	int res = 0;

	// Initialize sign as positive
	int sign = 1;

	// Initialize index of first digit
	int i = 0;

	// If number is negative,
	// then update sign
	if (str[0] == '-') {
		sign = -1;

		// Also update index of first digit
		i++;
	}

	// Iterate through all digits
	// and update the result
	for (; str[i] != '\0'; ++i)
		res = res * 10 + str[i] - '0';

	// Return result with sign
	return sign * res;
}

// Driver code
int main()
{
	char str[] = "-123";

	// Function call
	int val = myAtoi(str);
	printf("%d ", val);
	return 0;
}

Vedi sotto altre implementazioni della funzione atoi(), più "robuste".

Altre implementazioni della funzione atoi

Questa implementazione gestisce vari tipi di errore. Se str è NULL o str non contiene caratteri numerici allora ritorna 0 come numero non valido.

// A simple C++ program for
// implementation of atoi

#include <stdio.h>

// A utility function to check
// whether x is numeric
bool isNumericChar(char x)
{
	return (x >= '0' && x <= '9') ? true : false;
}

// A simple atoi() function.
// If the given string contains
// any invalid character, then
// this function returns 0
int myAtoi(char str[])
{
	if (str[0] == '\0')
		return 0;

	// Initialize result
	int res = 0;

	// Initialize sign as positive
	int sign = 1;

	// Initialize index of first digit
	int i = 0;

	// If number is negative,
	// then update sign
	if (str[0] == '-')
	{
		sign = -1;

		// Also update index of first digit
		i++;
	}

	// Iterate through all digits of
	// input string and update result
	for (; str[i] != '\0'; ++i)
	{

		// You may add some lines
		// to write error message
		if (isNumericChar(str[i]) == false)
			return 0;

		// to error stream
		res = res * 10 + str[i] - '0';
	}

	// Return result with sign
	return sign * res;
}

// Driver program to test above function
int main()
{
	char str[] = "-134";
	int val = myAtoi(str);
	printf("%d ", val);
	return 0;
}

L'output:

-134

Un'ultima implementazione, che gestisce i quattro casi limite:

  • Scarta tutti gli spazi iniziali, eventuali;

  • Il segno del numero;

  • l'overflow;

  • Gli input invalidi;

Per rimuovere gli spazi iniziali si esegue un loop finché un carattere di tipo cifra è raggiunto. Se il numero è più grande o uguale a INT_MAX/10, allora ritorna INT_MAX se il segno è positivo o INT_MIN se il segno è negativo. Negli altri casi è gestito come in precedenza.

Simulazione del comportamento con un dato di input:

L'implementazione:

// A simple C program for
// implementation of atoi
#include <stdio.h>
#include <limits.h>

int myAtoi(const char str[])
{
	int sign = 1, base = 0, i = 0;
	
	// if whitespaces then ignore.
	while (str[i] == ' ') 
	{
		i++;
	}
	
	// sign of number
	if (str[i] == '-' || str[i] == '+') 
	{
		sign = 1 - 2 * (str[i++] == '-');
	}

	// checking for valid input
	while (str[i] >= '0' && str[i] <= '9') 
	{
		// handling overflow test case
		if (base > INT_MAX / 10
			|| (base == INT_MAX / 10 
			&& str[i] - '0' > 7)) 
		{
			if (sign == 1)
				return INT_MAX;
			else
				return INT_MIN;
		}
		base = 10 * base + (str[i++] - '0');
	}
	return base * sign;
}


// Driver Code
int main()
{
	char str[] = " -123";

	// Functional Code
	int val = myAtoi(str);
	printf("%d ", val);
	return 0;
}
// This code is contributed by Yogesh shukla.

L'output:

-123

Complexity Analysis for all the above Approaches:

  • Time Complexity: O(n). Only one traversal of string is needed.

  • Space Complexity: O(1). As no extra space is required.

Convertire da intero a sequenza di caratteri

Nel linguaggio C, la funzione itoa, esegue la funzionalità inversa, cioè converte un intero nella corrispondente sequenza di caratteri ASCII.

char *  itoa ( int value, char * str, int base );

Esempio di utilizzo della funzione:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    int a=54325;
    char buffer[20];
    itoa(a,buffer,2);   // here 2 means binary
    printf("Binary value = %s\n", buffer);
 
    itoa(a,buffer,10);   // here 10 means decimal
    printf("Decimal value = %s\n", buffer);
 
    itoa(a,buffer,16);   // here 16 means Hexadecimal
    printf("Hexadecimal value = %s\n", buffer);
    return 0;
}

L'output:

Binary value = 1101010000110101
Decimal value = 54325
Hexadecimal value = D435

Siccome in C itoa non è una funzione dello standard C non è presente in molti compilatori (contrariamente ad atoi che fa parte dello standard C).

Si può utilizzare la funzione sprintf come alternativa a itoa. E' solo la metà buona come la funzione itoa perché non si può specificare la base a cui convertire il numero.

sprintf prende tre argomenti.

Il primo deve essere una variabile di tipo char *, che significa che tu puoi utilizzare un array di char, ma bisogna che sia abbastanza grande da contenere il numero convertito.

Il secondo argomento è la stringa contenente la specifica del formato, dipendendo sul formato del numero che si vuole convertire.

Il terzo argomento è il numero che si vuole convertire a stringa.

sprintf ritorna il numero di caratteri della stringa (senza però il carattere null).

Questo esempio converte alcuni numeri in formato stringa, a stampa in output il risultato:

#include <stdio.h>

int main() {
  char str[10]; /* MUST be big enough to hold all 
                  the characters of your number!! */
  int i;

  i = sprintf(str, "%o", 15);
  printf("15 in octal is %s\n",   str);
  printf("sprintf returns: %d\n\n", i);

  i = sprintf(str, "%d", 15);
  printf("15 in decimal is %s\n", str);
  printf("sprintf returns: %d\n\n", i);

  i = sprintf(str, "%x", 15);
  printf("15 in hex is %s\n",     str);
  printf("sprintf returns: %d\n\n", i);

  i = sprintf(str, "%f", 15.05);
  printf("15.05 as a string is %s\n", str);
  printf("sprintf returns: %d\n\n", i);

  return 0;
}

L'output:

15 in octal is 17
sprintf returns: 2

15 in decimal is 15
sprintf returns: 2

15 in hex is f
sprintf returns: 1

15.05 as a string is 15.050000
sprintf returns: 9

Una nostra implementazione di itoa potrebbe essere:

#include <stdio.h>
  
void my_reverse(char str[], int len);
char* my_itoa(int num, char* str, int base);
 
int main() {
    int i, b;
    char charArray[128];
    printf("Enter a number and base\n");
    scanf("%d %d", &i, &b);
     
    printf("String : %s", my_itoa(i, charArray, b));
    return 0;
}
 
/* 
* function to reverse a string  
*/
void my_reverse(char str[], int len)
{
    int start, end;
    char temp;
    for(start=0, end=len-1; start < end; start++, end--) {
        temp = *(str+start);
        *(str+start) = *(str+end);
        *(str+end) = temp;
    }
}
 
char* my_itoa(int num, char* str, int base)
{
    int i = 0;
    bool isNegative = false;
  
    /* A zero is same "0" string in all base */
    if (num == 0) {
        str[i] = '0';
        str[i + 1] = '\0';
        return str;
    }
  
    /* negative numbers are only handled if base is 10 
       otherwise considered unsigned number */
    if (num < 0 && base == 10) {
        isNegative = true;
        num = -num;
    }
  
    while (num != 0) {
        int rem = num % base;
        str[i++] = (rem > 9)? (rem-10) + 'A' : rem + '0';
        num = num/base;
    }
  
    /* Append negative sign for negative numbers */
    if (isNegative){
        str[i++] = '-';
    }
  
    str[i] = '\0';
 
    my_reverse(str, i);
  
    return str;
}

Output:

Enter a number and base
1234 10
String : 1234
Enter a number and base
-1234 10
String : -1234
Enter a number and base
10 2
String : 1010

Last updated

Was this helpful?