Duda con puntero a arreglo de caracteres

Iniciado por dato000, 30 Noviembre 2012, 14:51 PM

0 Miembros y 1 Visitante están viendo este tema.

dato000

Buenas, resulta que tengo el siguiente ejercicio:

Citar
Escribir un programa en el que se lean 20 lineas de texto, cada linea con un máximo de 80 caracteres (yo lo hice con 4 lineas de texto). Mostrar por pantalla el número de vocales que tiene cada linea.

Y me resulto este código:


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

# define L 4;

void datos(char *ln);

int main()
{
    int rep;
    char linea[80];
    char *l;
    l = &linea[0];
    for(rep=0; rep < 4; rep++)
        datos(l);
    return 0;
}

void datos(char *ln){
    int i;
    int cont=0;

    printf("Escriba las linea\n");
    fgets(ln,80,stdin);
    for(i=0; i<strlen(ln); i++){
        if(*(ln+i)=='a' || *(ln+i)=='e' || *(ln+i)=='i' || *(ln+i)=='o' || *(ln+i)=='u')
            cont++;
    }
    printf("numero de vocales en la frase:  %d \n\n", cont);
}


Pero algo no me termina de convencer, no se muy bien como usar punteros, y algo me parece que esta mal en el programa, uds que piensan, no necesito rehacer el ejercicio o ayuda con la tarea, solo lo hago para pasar el tiempo, y solo quiero saber opiniones, porque este código, pues, seguro que se puede mejorar, aún sigo practicando el uso de apuntadores.



xiruko

yo no le veo nada malo al codigo, lo unico que si usas la funcion strlen() deberias incluir string.h. te compila el codigo?

ahora bien, quizas si que hay algo que sobra. tu puntero a caracter l realmente no tiene mucha utilidad, ya que apunta al mismo sitio que linea (en C, si declaras una cadena de caracteres como char linea[20], linea es un puntero que apuntar al primer caracter de la cadena). asi pues, podrias prescindir de l y llamar a tu funcion asi: datos(linea);

luego para comprobar si cada caracter es una vocal, lo haces con esta sintaxis: *(ln+i), y esto es equivalente a ln[ i] que quizas es mas sencillo de leer. aunque ambas estan bien asi que eso ya es a tu gusto.

si quieres hacerlo con aritmetica de punteros para practicar, podrias hacer algo asi en tu funcion datos() y asi ademas te ahorras usar strlen() e incluir la string.h:

void datos(char *ln){

    int cont=0;

    printf("Escriba la linea:\n");
    fgets(ln,79,stdin); // 79 para dejar espacio al NULL del final
    for(; *ln; ln++){
        if( *ln=='a' || *ln=='e' || *ln=='i' || *ln=='o' || *ln=='u')
            cont++;
    }
    printf("numero de vocales en la frase:  %d \n\n", cont);
}


y por ultimo, diria que no hace falta incluir stdlib.h ya que no usas ninguna funcion ni macro de ahi.

un saludo!

durasno

Hola! para mi gusto lo que se puede agregar es que la funcion retorne algo, en este caso la cantidad de vocales osea cont, asi no se ejecuta todo en la funcion(pero esto es una cuestion de gustos)


Saludos
Ahorrate una pregunta, lee el man

dato000

Cita de: xiruko en 30 Noviembre 2012, 15:25 PM
yo no le veo nada malo al codigo, lo unico que si usas la funcion strlen() deberias incluir string.h. te compila el codigo?

ahora bien, quizas si que hay algo que sobra. tu puntero a caracter l realmente no tiene mucha utilidad, ya que apunta al mismo sitio que linea (en C, si declaras una cadena de caracteres como char linea[20], linea es un puntero que apuntar al primer caracter de la cadena). asi pues, podrias prescindir de l y llamar a tu funcion asi: datos(linea);

luego para comprobar si cada caracter es una vocal, lo haces con esta sintaxis: *(ln+i), y esto es equivalente a ln[ i] que quizas es mas sencillo de leer. aunque ambas estan bien asi que eso ya es a tu gusto.

si quieres hacerlo con aritmetica de punteros para practicar, podrias hacer algo asi en tu funcion datos() y asi ademas te ahorras usar strlen() e incluir la string.h:

void datos(char *ln){

    int cont=0;

    printf("Escriba la linea:\n");
    fgets(ln,79,stdin); // 79 para dejar espacio al NULL del final
    for(; *ln; ln++){
        if( *ln=='a' || *ln=='e' || *ln=='i' || *ln=='o' || *ln=='u')
            cont++;
    }
    printf("numero de vocales en la frase:  %d \n\n", cont);
}


y por ultimo, diria que no hace falta incluir stdlib.h ya que no usas ninguna funcion ni macro de ahi.

un saludo!

Ummm pues como voy en el capitulo de punteros en mi pequeño librito de 700 pags, pues estoy practicando indexado y toda esa basura XD.

Pues sterlen() me funciona sin problemas, y va de lujo, ya que scanf() ni gets() funciona para leer caracteres que siguen a un espacio.

no sabia que podria usar el puntero en el ciclo for de esa manera, va de lujo!!! y tienes razón, es mejor dejar el NUL (seria como '\0" verdad??)


Cita de: durasno en 30 Noviembre 2012, 16:32 PM
Hola! para mi gusto lo que se puede agregar es que la funcion retorne algo, en este caso la cantidad de vocales osea cont, asi no se ejecuta todo en la funcion(pero esto es una cuestion de gustos)


Saludos

Estaba pensando eso, pero realmente como el ejercicio no indica explicitamente que "retorne" un valor, simplemente lo imprimi directo en pantalla, de todas maneras, los otros ejercicios que tengo pendientes si hay que manejar funciones con retorno de valor.


Vale gente muchas gracias, es un alivio que no vaya tan perdido con apuntadores  ;-) ;-)



rir3760

#4
Solo un comentario:
fgets(ln,79,stdin); // 79 para dejar espacio al NULL del final
Cuando se llama a la función sus argumentos indican donde se localiza el contenedor, la capacidad de este en caracteres y el stream donde se extraerán estos, respectivamente.

La función extrae caracteres del stream y los almacena en el contenedor hasta que se cumpla uno de dos escenarios:

A) El numero de caracteres almacenados es igual a N-1.
B) El carácter almacenado es '\n'.

Cuando eso sucede la función almacena el carácter '\0' en la siguiente posicion y termina retornando la dirección del contenedor (o NULL en caso de error o fin de archivo). Por ende no es necesario reservar manualmente un carácter. En resumen la forma politicamente correcta es:
#define NUM_CHARS  128 /* Solo un ejemplo */

/* ... */

char linea[NUM_CHARS];

/* ... */

fgets(linea, NUM_CHARS, stdin);


----

Pero cuando se utiliza la función scanf (familia incluida) con el especificador "%Ns" si se debe tener esa precaución ya que ella almacena como máximo el numero de caracteres indicados y a continuación almacena el '\0'. Con ella debemos utilizar:
#define NUM_CHARS  128 /* Solo un ejemplo */

/* ... */

char linea[NUM_CHARS];

/* ... */

scanf("%127s", linea);


Para automatizar la generación de la cadena de formato "%127s" se puede utilizar (por supuesto previamente a la llamada) la función sprintf con un array auxiliar.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

xiruko

Cita de: rir3760 en 30 Noviembre 2012, 18:24 PM
La función extrae caracteres del stream y los almacena en el contenedor hasta que se cumpla uno de dos escenarios:

A) El numero de caracteres almacenados es igual a N-1.
B) El carácter almacenado es '\n'.

vaya gracias, desde siempre que dejaba un espacio para el NULL del final ya que no tenia ni idea de que la misma funcion ya lo controlaba.

Cita de: dato000 en 30 Noviembre 2012, 18:06 PM
y tienes razón, es mejor dejar el NUL (seria como '\0" verdad??)

bueno rir3760 ya ha dejado claro el asunto, asi que en realidad no hace falta que tu dejes un espacio extra al final para el NULL (fallo mio :rolleyes:). y si, NULL es el caracter '\0'.

un saludo!