Saltar a contenido

Sol Intro Ptr

Solución al Ejercicio de Autoevaluación

Esta entrada presenta una posible solución al ejercicio con strtol(). Utiliza la llamada al sistema isdigit() cuya declaración es la siguiente:

#include <ctype.h>
int isdigit(int c);
int isdigit_l(int c, locale_t locale);
/*
       The isdigit() and isdigitl() functions shall return non-zero if
       c is a decimal digit; otherwise, they shall return 0.
 */

Claves del código solución

  • Lectura desde stdin mediante fgets(3p)Linux manual page
    #include <stdio.h>
    /*
     * The fgets() function shall read bytes from stream into the array
     * pointed to by s until n-1 bytes are read, or a <newline> is read
     * and transferred to s, or an end-of-file condition is encountered
     */
    char *fgets(char *restrict s, int n, FILE *restrict stream);
    
  • Arrays vs punteros

        char str[MAX+1];
        char *ptr = str;
    

  • Ejemplos de ejecución: "abc30", "30abc", "a 3 c", "01 23 45 67 89"

  • Salida del programa:
    LabPtrSol.png

Orden de compilación

gcc -Wall -Wextra -ansi -pedantic -Werror -g strtol_sol.c -o bin/strtol_sol

Pregunta

Los siguientes bloques de código, ¿son correctos?

Bloque nº 1

    char str[MAX+1];
    while(fgets(str, MAX+1, stdin)) {
        /*
         * Código ...
         */
    }

Bloque nº 2

    char *ptr;
    while(fgets(ptr, MAX+1, stdin)) {
        /*
         * Código ...
         */
    }

Código C solución del ejercicio

/*
 * Definición de ctes simbólicas. Tarea para el preprocesador
 */
#define OK 0
#define MAX 5

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


/*
 * Versión con isdigit()
 */
int main()
{
    char str[MAX+1];
    char *ptr = str;
    int l;
    long nums[MAX] = {0, 0, 0, 0, 0};
    long ret = 1;
    int i = 0, j;

    printf("==========================================================\n");
    printf("\tMemoria requerida (bytes) por str:\t%d\n", (int) sizeof(str));
    printf("\tMemoria requerida (bytes) por ptr:\t%d\n", (int) sizeof(ptr));
    printf("\tMemoria requerida (bytes) por ret:\t%d\n", (int) sizeof(ret));
    printf("\tMemoria requerida (bytes) por nums:\t%d\n", (int) sizeof(nums));
    printf("==========================================================\n\n");


    memset(str, 0, MAX+1);
    printf("Teclear strings (max %d caracteres). ^D para salir:\n", MAX);
/*
 * The fgets() function shall read bytes from stream into the array
 * pointed to by s until n-1 bytes are read, or a <newline> is read
 * and transferred to s, or an end-of-file condition is encountered
 */
    while(fgets(ptr, MAX+1, stdin)) {
        l = (int) strlen(ptr);
      if(l > 0 && str[l-1] == '\n')
      /*
       * Eliminar '\n' residual
       */
        str[l-1] = '\0';
      else
        printf("\tLeídos %d chars: %s\n", l, ptr);
      do {
        ret = strtol(ptr, &ptr, 10);
        if (ret != 0) {
          printf("\tEl número es %ld ", ret);
          if(strlen(ptr) > 0)
            printf("y el resto del array es %s\n", ptr);
          else
            printf("\n");
          if (i < MAX)
            nums[i++] = ret;
        }
        else {
            /*
             * Avanzar mientras no encuentre dígito
             */
             while(*ptr != 0 && isdigit(*ptr) == 0)
                ptr++;
        }
      } while (strlen(ptr) > 0);
    /*
     * Reiniciar para el siguiente número
     */
      ptr = str;
      memset(ptr, 0, MAX+1);
    }
    /*
     * Imprimir array de números
     */
    if (i>0) {
      printf("\nnums[]={%ld", nums[0]);
      for(j = 1; j < i; j++)
        printf(",%ld", nums[j]);
      printf("}\n");
    }

    return(OK);
}