La función atoi y strcat en C
Tags: c, atoi, csaga, strcat
Published: 2024-07-02 05:53:13

¡Hola! Me encuentro aprendiendo el lenguaje de programación C y como herramienta estoy utilizando el libro de "The C Programming Language" de Kernighan y Ritchie. A lo largo de mi aprendizaje estaré compartiendo todo lo que me parezca interesante o retador. Todos estos posts estarán unidos con la etiqueta `#csaga`.

Actualmente acabo de concluir el segundo capítulo y de él rescato dos problemas que me parecen interesantes a los cuales daremos solución mediante funciones.

Comencemos con el primer problema: Dada una cadena de dígitos regresar su equivalente numérico. 

Vamos a resolver este problema mediante un función que llamaremos `atoi`, en ella recibiremos una cadena (arreglo de caracteres) que nombraremos `s[]`, también es claro que la función debe retornar un `int`. De aquí en adelante dividiremos el problema en dos partes:

1. Es natural asumir que lo primero que debemos hacer es recorrer el arreglo, esto lo podemos hacer con un ciclo `for`. Podemos inicializar el ciclo `for` como siempre con un contador `i = 0`, pero debemos establecer un criterio para salir del ciclo. En este caso los autores decidieron aprovechar el hecho de que en C, los caracteres están representados por sus valores ASCII. Por ejemplo `'0'` tiene un valor ASCII de `48`, `'1'` tiene el valor `49` y así, hasta el carácter `'9'` que tiene el valor `57`. Entonces los valores ASCII válidos para nuestro ciclo están entre `48` y `57` inclusivos, por lo que podemos formar la sentencia:
`for (i=0; s[i] >= '0' && s[i] <= '9'; ++i)`. La condición de salida del ciclo es clara, ya que si se llega final del arreglo de caracteres este siempre es `'\0'` que representa el carácter nulo, cuyo valor en ASCII es 0. También, si hubiera un valor que no fuera un dígito se saldría del ciclo, por las razones antes mencionadas.

2. Una vez que estamos recorriendo el arreglo debemos convertir el digito en el entero que representa. Esto lo podemos hacer con : `(s[i] - '0')`. La sentencia anterior toma el valor ASCII del arreglo y le resta el valor ASCII de `'0'`, dando como resultado el entero deseado. Ejemplo: 
Supongamos `s[i]=5`, entonces `s[i] - 0` es equivalente a `53 - 48 = 5`. Por último, queda acomodar el número en su posición pertinente (como unidad, decena, centena, etc.) Lo cual se consigue estableciendo un `n = 0` y luego actualizando en cada iteración con `n = 10 * n + (s[i] - '0')`. 
 
Con todo lo anterior, nuestra función deseada queda como:

```c
int atoi(char s[]){

	int i, n;
	n=0;

	for (i=0; s[i] >= '0' && s[i] <= '9'; ++i){
		n = 10 * n + (s[i] - '0');
	}
        return n;
}
```

Segundo problema: Dadas dos cadenas `s[]` y `t[]` concatenar la cadena `t` al final de la cadena `s`. 

Para hacer el problema más fácil el libro asume que en `s` hay suficiente espacio para almacenar la combinación. Ahora, debemos comenzar definiendo una función que llamaremos `strcat` que debe recibir dos cadenas `s[]` y `t[]`, esta función no necesita regresar un valor. Una manera de resolver el problema es primero posicionaros al final de la primera cadena `s[]`. A partir del final de la primera cadena debemos de empezar a guardar los elementos de la segunda cadena `t[]`.

Para llegar al final de la primera cadena podemos comenzar con un contador `i = 0` e ir aumentando el valor de `i` hasta el final del arreglo, esto se logra cuando alcanzamos el valor `'\0'`, el cual marca el final de todo arreglo de caracteres. Así podemos tener el siguiente código:

```c
while(s[i] != '\0'){
    i++;
}
```

Ahora que estamos posicionados en el fin de `s` debemos de empezar a copiar los valores de `t`. Para esto necesitamos empezar otro contador `j = 0` y asignar `s[i] = t[j]`, recordemos que el valor de `i` ya esta al final de la primera cadena. Luego debemos incrementar ambos índices y repetir el proceso hasta que encontremos el carácter `'\0'` que marca el fin de la cadena en `t`. Todo lo anterior lo podemos lograr mediante la sentencia: 

```c
while ((s[i++] = t[j++]) != '\0') {
   ;
}
```
Sé que me estoy repitiendo, pero con la finalidad de que quede todo claro. El código anterior primero asigna el carácter `t[j]` a `s[i]`, luego incrementa el valor de `i` y de `j` hasta encontrar el final de `t`.
Teniendo en cuenta lo anterior nuestra función quedaría como: 

```c
void strcat(char s[], char t[]) {
    int i = 0, j = 0;

    while (s[i] != '\0') {
        i++;
    }

    while ((s[i++] = t[j++]) != '\0') {
        ;
    }
}
```

Antes de terminar el post quisiera decir que el lector debe tener en cuenta que ando aprendiendo, en caso de existir algún error, por favor, con toda libertad me lo pueden hacer saber en comentarios. 

Gracias por leer!!!!