Eine ziemlich häufiges Problem bei der Anwendungsentwicklung ist die Umwandlung von Zeichenfolgen in eine Ganzzahl zur Weiterverarbeitung. Bei C oder C++ ist atoi() der einfachste Weg, um vom char array zum int zu kommen. Leider ermöglicht atoi() keine präzise Fehlererkennung, weil eine ungültige Eingabe ebenso wie die korrekte Eingabe “0” zum Ergebnis “0” führt:
$ cat atoi.c 
#include <stdio.h>
#include <stdlib.h>
int main() { 
  printf("%i - %i ", atoi("invalid"), atoi("0")); 
  return 0; 
} 
$ gcc -Wall -pedantic atoi.c -o atoi 
$ ./atoi 0 - 0
Meist wird empfohlen, strtol() zu nutzen. Diese Funktion ist mächtiger und v.a. brauchbarer bei der Fehlererkennung. Aber wieviel Performance kostet strtol() im Vergleich zu atoi()? Ein Shell-Script
#!/bin/bash
function instr_by_cmd()
{
	valgrind --tool=callgrind --callgrind-out-file=/dev/null "$1" 2>&1 | grep refs | sed 's/^.*\s//;s/,//'
}
function print_head()
{
	echo -e "\nTeste $1()";
	printf "%15s | %15s | %15s\n" Test Instruktionen Ergebnis
	echo "----------------+-----------------+----------------"
}
# usage: test_source "headers" "template" "replacement"
function test_source()
{
	rm /tmp/source.c 2>/dev/null
	for CASE in "${TESTCASES[@]}"
	do
		for HEADER in $1
		do
        		echo "#include <$HEADER>" >> /tmp/source.c
		done
		echo "${2/CASE/$CASE}" >> /tmp/source.c
		gcc /tmp/source.c -o /tmp/source 2>/dev/null
		INSTR=$(instr_by_cmd "/tmp/source")
		RES=$(/tmp/source);
		sed -i 's/'$3'/'$RES'/' /tmp/source.c
		gcc /tmp/source.c -o /tmp/source 2>/dev/null
		INSTR=$(($INSTR-$(instr_by_cmd "/tmp/source")))
		printf "%15s | %15s | %15s\n" ">$CASE<" $INSTR $RES
		rm /tmp/source.c 
	done
	rm atoi 2>/dev/null
}
TESTCASES=( "4" "42" "4\n2" "424242" " 42 " "answer: 42" "2147483648" "-2147483649" "\n42\n" )
print_head atoi
test_source "stdlib.h stdio.h" "int main(){char * rem=0;char * input=\"CASE\";printf(\"%i\n\", atoi(input));return 0;}" "atoi(input)"
print_head strtol
test_source "stdlib.h stdio.h" "int main(){char * rem=0;char * input=\"CASE\";printf(\"%ld\n\", strtol(input,&rem,10));return 0;}" "strtol(input,&rem,10)"
bringt zusammen mit valgrind auf der Testplattform (Core 2 Duo E6600) folgende Ergebnisse für atoi()
| Test | Instruktionen | Ergebnis | 
|---|---|---|
| >4< | 883 | 4 | 
| >42< | 903 | 42 | 
| >4\n2< | 894 | 4 | 
| >424242< | 983 | 424242 | 
| > 42 < | 920 | 42 | 
| >answer: 42< | 867 | 0 | 
| >2147483648< | 1063 | -2147483648 | 
| >-21474836489< | 1064 | 2147483647 | 
| >\n42\n | 920 | 42 | 
und für strtol()
| Test | Instruktionen | Ergebnis | 
|---|---|---|
| >4< | 921 | 4 | 
| >42< | 941 | 42 | 
| >4\n2< | 932 | 4 | 
| >424242< | 1021 | 424242 | 
| > 42 < | 958 | 42 | 
| >answer: 42< | 912 | 0 | 
| >2147483648< | 1101 | 2147483648 | 
| >-21474836489< | 1102 | -2147483649 | 
| >\n42\n | 958 | 42 |