/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Ejercicios de Programación
Ir a página Anterior  1, 2, 3, 4, 5, 6, 7  Siguiente
 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 07/08/2012 1:18 pm
Título:

Sorancio escribió:
Hazlo sin usar fscanf]

Vale, tú tienes mucha más fé que yo en mis posibilidades.......
Buscando, buscando me he encontrado con una función muy interesante : "strtok", que permite separar una cadena según que signos aparezcan. He logrado con ella que lea cualquier cantidad de números por línea que estén separados por comas- como corresponde a un fichero csv-.En el código que te dejo he cambiado adrede los datos para que se compruebe lo que digo.
Código:
1,2,3,5,6
4,2,3
2,1,1,7,1,1
Luego los paso a enteros con "atoi" y ya sólo me quedará implementar el mayor y menor.
Embarassed Embarassed Embarassed Embarassed Embarassed Embarassed
Pero "me" he planteado una variante , que los números fueran con decimales. En principio no habría problema, pensé - pardillo que soy un pardillo-, utilizo "atof", declarando el array que los guarda como float y ...y una merde!!!....salen unos números "raros", "raros".....
Así que por hoy me mantengo con números enteros a la espera de alguna solución para los decimales...
Y así va el código:
Código:
#include <stdio.h>
#include <string.h>
main()
{
    int i,j,a[10]={0},minimo [2],maximo [2];

    char * pch;
    FILE* fichero;
    fichero = fopen("C:\\ejercicio2.csv", "wt");
    fputs("1,2,3,5,6\n", fichero);
    fputs("4,2,3\n", fichero);
    fputs("2,1,1,7,1,1", fichero);

    fclose(fichero);
    char nombre[80] = "C:\\ejercicio2.csv";
    char linea[81];
    fichero = fopen(nombre, "rt");
    if (fichero == NULL)
        {
            printf("No existe el fichero!\n");
            return 1;
        }
    while (! feof(fichero))
        {
            fgets(linea, 80, fichero);
            puts(linea);
            i=j=0;
            pch = strtok (linea,",");
            while (pch != NULL)
              {
                a[i]=atoi (pch);
                printf ("a[%d] = %d \t",i,a[i]);
                printf ("%s\n",pch);
                pch = strtok (NULL, ",");
                i++;
              }
        }
fclose(fichero);
}
Volver arriba
Sorancio



Registrado: 29 May 2009
Mensajes: 1157
Ubicación: España

MensajePublicado: 07/08/2012 10:36 pm
Título:

Vas a tener que ir haciendo pruebas :).

Quizá deberías buscar información sobre como funciona atof (el nombre engaña ya que devuelve un double no un float). Otra forma es hacer un sscanf (ojo, con 2 s) y coger así el número, ya que veo que tienes experiencia en ello :).
_________________
Mi página web (en inglés):
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 08/08/2012 4:09 am
Título:

Sorancio escribió:
durasno escribió:
Hola! una pregunta con respecto a:
Cita:
evitar el uso de la función "feof"

¿¿hay algun motivo en particular por el cual no se deba usar feof??? ¿o solo por este ejercicio se lo dijiste?


Saludos


feof sólo devuelve true cuando otra función de lectura ha llegado a final de archivo. Dependiendo de la estructura del bucle puede llevar a ejecutar un ciclo más Smile.

Efectivamente me lleva a un elemento de array de más.Lo he logrado solventar con :
Código:
pch = strtok (linea,",\n");

Pero me gustaría saber si existe otra forma de evitarlo al leer el final del fichero , vamos que no sea con eof.
Volver arriba
Sorancio



Registrado: 29 May 2009
Mensajes: 1157
Ubicación: España

MensajePublicado: 08/08/2012 4:18 am
Título:

fgets devuelve NULL cuando llega al final del fichero :)
_________________
Mi página web (en inglés):
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 08/08/2012 4:21 am
Título:

Sorancio escribió:
Vas a tener que ir haciendo pruebas Smile.

Quizá deberías buscar información sobre como funciona atof (el nombre engaña ya que devuelve un double no un float). Otra forma es hacer un sscanf (ojo, con 2 s) y coger así el número, ya que veo que tienes experiencia en ello Smile.

Iré probando cosas, ya que atof , declarando el array con double, no me toma los decimales ....y con sscanf he empezado.
Como veras, cambié la lista de números que distes en el ejercicio para complicarlo un poco . ya que así no está "predeterminado" la cantidad de números a leer.Además, como la lista por línea podría ser larga, me pareció más interesante para hallar mayor y menor ordenarla primero; luego comparando último con penúltimo y primero con segundo determino si hay máximo y mínimo y cual es:
Código:
#include <stdio.h>
#include <string.h>
#define NOM_ARCHIVO  "C:\\ejercicio2.csv"
main()
{
    int i,j,k,minimo ,maximo ;
    int a[10]={0};
    char * pch;
    FILE* fichero;
    fichero = fopen("NOM_ARCHIVO", "wt");
    fputs("2,1,3,5,6\n", fichero);
    fputs("4,2,3\n", fichero);
    fputs("2,1,1,7,1,1", fichero);

    fclose(fichero);
    char nombre[80] = "NOM_ARCHIVO";
    char linea[81];
    fichero = fopen(nombre, "rt");
    if (fichero == NULL)
        {
            printf("No existe el fichero!\n");
            return 1;
        }
    /*if ((fichero = fopen(NOM_ARCHIVO, "r"))*/
    while (! feof(fichero))
        {
            fgets(linea, 80, fichero);
            puts(linea);
            i=j=0;
            pch = strtok (linea,",\n");
            while (pch != NULL)
              {
                a[i]=atoi (pch);
                printf ("a[%d] = %d \t",i,a[i]);
                printf ("%s\n",pch);
                pch = strtok (NULL, ",\n");
                i++;
              }
            /*printf ("a[%d] = %lf  \n",i,a[i]);*/
    printf("\n Presione cualquier tecla para continuar... \n\n");
    getch();
    int k,j,temp;
    for (j=1; j< i; j++)
            for (k=0; k< i-j; k++)
                if (a[k] > a[k+1])
                {
                    temp = a[k];
                   a[k] = a[k+1];
                    a[k+1] = temp;
                }printf("\n\n\t");
    for (k=0; k< i; k++)
        printf ("%d ", a[k]);
        printf ("\n\n");
        /*printf ("%d    %d",i, a[i-1]);*/
    if (a[i-1]==a[i-2]) printf("\nNo existe mayor\t");
    else maximo = a[i-1];
    printf("\nMayor : %d\t",maximo);
    if (a[0]==a[1]) printf("\nNo existe menor\n");
    else minimo = a[0];
    printf("\nMinimo : %d\n",minimo);
    printf ("\n\n");

            }
fclose(fichero);
}
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 08/08/2012 11:49 am
Título:

Cita:
Perdón, se me había olvidado el cálculo del máximo y mínimo global.Aquí si están:

Código:
#include <stdio.h>
#include <string.h>
#define NOM_ARCHIVO  "C:\\ejercicio2.csv"
int main()
{
    int i,j,k,minimo ,maximo,max_global=1.e-12,min_global=1.e+12 ;
    int a[10]={0};
    char * pch;
    FILE* fichero;
    fichero = fopen("NOM_ARCHIVO", "wt");
    fputs("2,1,3,5,6\n", fichero);
    fputs("4,2,3\n", fichero);
    fputs("2,1,1,7,1,1", fichero);

    fclose(fichero);
    char nombre[80] = "NOM_ARCHIVO";
    char linea[81];
    fichero = fopen(nombre, "rt");
    if (fichero == NULL)
        {
            printf("No existe el fichero!\n");
            return 1;
        }
    /*if ((fichero = fopen(NOM_ARCHIVO, "r"))*/
    while (! feof(fichero))
        {
            fgets(linea, 80, fichero);
            puts(linea);
            i=j=0;
            pch = strtok (linea,",\n");
            while (pch != NULL)
              {
                a[i]=atoi (pch);
                printf ("a[%d] = %d \t",i,a[i]);
                printf ("%s\n",pch);
                pch = strtok (NULL, ",\n");
                i++;
              }
            /*printf ("a[%d] = %lf  \n",i,a[i]);*/
            printf("\n Presione cualquier tecla para continuar... \n\n");
            getch();
            int k,j,temp;
            for (j=1; j< i; j++)
                    for (k=0; k< i-j; k++)
                        if (a[k] > a[k+1])
                        {
                            temp = a[k];
                           a[k] = a[k+1];
                            a[k+1] = temp;
                        }printf("\n\n\t");
            for (k=0; k< i; k++)
                printf ("%d ", a[k]);
                printf ("\n\n");
                /*printf ("%d    %d",i, a[i-1]);*/
            if (a[i-1]==a[i-2]) printf("\nNo existe mayor\t");
            else {
                maximo = a[i-1];
                if (maximo>max_global) max_global=maximo;
                }
            printf("\nMayor : %d\t",maximo);
            if (a[0]==a[1]) printf("\tNo existe menor\n");
            else {
                minimo = a[0];
                if (minimo<min_global) min_global=minimo;
            printf("\tMinimo : %d\n",minimo);
            printf ("\n\n");
                }
        }
    printf("\nMayor global: %d\t",max_global);
    printf("\tMinimo global: %d\n",min_global);
    printf("\n Presione cualquier tecla para continuar... \n\n");
    getch();
    fclose(fichero);
    return 0;
}
Volver arriba
Pantalàimon_



Registrado: 17 Jul 2007
Mensajes: 1344

MensajePublicado: 08/08/2012 3:27 pm
Título:

Hola leosan.

Código:
Eint i,j,k,minimo ,maximo,max_global=1.e-12,min_global=1.e+12 ;

Los valores que le das a min_global y max_global en mi caso que tengo int de 4 bytes se exceden al valor mínimo y máximo que tienen el tipo int. Si quieres asignar a dichas variables el máximo valor y el mínimo deberías usar las macros de la cabecera limits.h . Infórmate y encuentra las macros adecuadas a usar.

Usando el modo pedántico también se queja del uso de getch, de no haber declarado la cabecera necesaria para atoi y de que la variable k no se usa.

Por otro lado te animo a que encuentres otras maneras de saber si no existe mínimo o máximo sin tener que ordenar los números. Ordenar los números para esta labor es poco eficiente, hay otras maneras de hacerlo sin tener que ordenarlos.

PD.: Esto ya es muy pero que muy subjetivo, pero tanta letra en la salida por pantalla acaba siéndome molesta. No digo que para testear que el código este mal hacerlo pero para ver si tu programa da buenos o malos resultados tengo que pararme demasiado rato a mirarlo y creo que si te ciñieras a la salida que expone Sorancio todo sería más directo y fácil. Pero ya digo, es una opinión con toda la subjetividad que conlleva.

Un saludo!
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 09/08/2012 5:05 am
Título:

[quote="Pantalàimon_"]
Cita:

Por otro lado te animo a que encuentres otras maneras de saber si no existe mínimo o máximo sin tener que ordenar los números. Ordenar los números para esta labor es poco eficiente, hay otras maneras de hacerlo sin tener que ordenarlos.

La verdad que al pensarlo un poco me pareció que , para variar, tienes razón.Así que me puse a ello.
Se me ocurrió que al recorrer el array una vez solamente podría localizar el máximo y para reconocer si dos valores del array tiene el mismo valor podría usar un "contador", más preciso creo que sería un flag.Y lo mismo para el mínimo.
Lo conseguido cumple con todo lo explicado antes y lo pedido por el ejercicio, pero me gustaría una opinión......me da que no he tomado el camino más sencillo...aunque funciona:
Cita:

Un saludo!

Código:
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define NOM_ARCHIVO  "C:\\ejercicio2.csv"
int atoi ();
int main()
{
    int i,j;
        long int minimo=LONG_MIN ,maximo=LONG_MAX,max_global=LONG_MIN,min_global=LONG_MAX;

    int a[10]={0};
    int contador_1=0,contador_2=0;
    char * pch;
    FILE* fichero;
    fichero = fopen("NOM_ARCHIVO", "wt");
    fputs("2,1,6,3,5,6\n", fichero);
    fputs("4,2,3\n", fichero);
    fputs("2,1,1,3,7,1,1", fichero);

    fclose(fichero);
    char nombre[80] = "NOM_ARCHIVO";
    char linea[81];
    fichero = fopen(nombre, "rt");
    if (fichero == NULL)
        {
            printf("No existe el fichero!\n");
            return 1;
        }
    while (! feof(fichero))
        {
            fgets(linea, 80, fichero);
            puts(linea);
            i=j=0;
            pch = strtok (linea,",\n");
            while (pch != NULL)
              {
                a[i]=atoi (pch);
                pch = strtok (NULL, ",\n");
                i++;
              }/*printf("\ni=%d  \t",i);*/
                for (j=0; j< i; j++)
                    {
                       if (a[j]> maximo )
                        {
                            maximo = a[j];
                           contador_1 = 1;
                        }
                        else if (a[j] == maximo )  contador_1 = 0;
                    }
                if (contador_1 == 1) printf("\nMayor : %d\t",maximo);
                if (contador_1 == 0) printf("\nNo existe mayor\t");
                max_global=maximo;
                maximo=-2147483647;
                for (j=0; j< i; j++)
                    {
                       if (a[j]<minimo )
                        {
                            minimo = a[j];
                            contador_2 = 1;
                        }
                        else if (a[j]==minimo ) contador_2 = 0;
                    }
                if (contador_2==1) printf("\tMinimo : %d\n\n",minimo);
                if (contador_2==0) printf("\tNo existe menor\n\n");
                min_global=minimo;
                minimo=2147483647;

                if (maximo>max_global) max_global=maximo;
                if (minimo<min_global) min_global=minimo;
        }
    printf("\nMayor global: %d\t",max_global);
    printf("\tMinimo global: %d\n",min_global);
    fclose(fichero);
    return 0;
}


Ultima edición por leosan el 09/08/2012 2:27 pm; editado 4 veces
Volver arriba
Pantalàimon_



Registrado: 17 Jul 2007
Mensajes: 1344

MensajePublicado: 09/08/2012 6:24 am
Título:

Hola leosan.
leosan escribió:

Código:
    int i=0,j=0,k,temp,minimo ,maximo,max_global=-2147483647,min_global=2147483647 ;

Corregido .

Corregido en parte. En el caso habitual en que el int ocupe 4 bytes, el máximo valor es 2147483647 y el mínimo valor es- atención- -2147483648. Pero nadie te asegura que el int no ocupe 2 bytes o 8. En este caso las constantes serían otras. En la cabecera limits.h que te recomendé que miraras están las macros con los valores máximos, mínimos de cada tipo. De manera que si usas esas macros puedes asegurar que los valores máximos y minímos serán los correspondientes a la máquina usada y el código compilado funcionará correctamente para toda máquina.

leosan escribió:
Pantalàimon_ escribió:
Usando el modo pedántico [...] se queja[...] de no haber declarado la cabecera necesaria para atoi [...]

[...] No sé que hacer con la queja de atoi.

Como te dije, debes usar la cabecera adecuada donde está el prototipo de atoi. ¿Cuál és la cabecera? ¡búscala! :)

Un saludo!
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 09/08/2012 1:37 pm
Título:

Pantalàimon_ escribió:
Justo me has pillado escribiendo la respuesta al orden, está antes de tu post.......y lo que acabas de comentar lo he incluido como creo que indicas....GRACIAS
Un saludo!
Volver arriba
Pantalàimon_



Registrado: 17 Jul 2007
Mensajes: 1344

MensajePublicado: 11/08/2012 4:30 pm
Título:

Hola leosan.
Enumeraré unas cuantas observaciones que he hecho sobre tu código:

1)En tu último código has corregido lo de atoi declarando el prototipo de la función manualmente. ¿Aún no has encontrado la cabecera donde está declarado el prototipo? Empiezo a pensar que se te escapa el significado de alguna palabra que digo en referencia a esto y te da cosa preguntar aquí o buscar en internet.

2)Veo que usas en algunos printf el formato para mostrar un tipo int %d cuando deberías usar el correspondiente "%ld" para long int.

3)El modo pedántico también me lanza un aviso de que en C90 no se pueden hacer declaraciones si no es al inicio de bloque como las siguientes:
Código:
    char nombre[80] = "NOM_ARCHIVO";
    char linea[81];


4)Recuerdo que escribiste buscando alguna forma alternativa para no usar feof:
leosan escribió:
Efectivamente me lleva a un elemento de array de más.Lo he logrado solventar con :

Código:
pch = strtok (linea,",\n");

Pero me gustaría saber si existe otra forma de evitarlo al leer el final del fichero , vamos que no sea con eof.

Y Sorancio te dio una:
Sorancio escribió:
fgets devuelve NULL cuando llega al final del fichero Smile

¿La has probado?

5) La salida de tu programa me da errónea para la primera cadena de números:
Código:

2,1,6,3,5,6


No existe mayor      No existe menor

Pues si que hay menor y es 1.

6) Tal como llamas a la función fgets, con 80 caracteres reservados por la cadena linea ya hay suficiente( no hacen falta 81). Revisa como funciona la función fgets y verás que es así.

Un saludo!
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 12/08/2012 4:15 am
Título:

Pantalàimon_ escribió:
Hola leosan.
Enumeraré unas cuantas observaciones que he hecho sobre tu código:

1)En tu último código has corregido lo de atoi declarando el prototipo de la función manualmente. ¿Aún no has encontrado la cabecera donde está declarado el prototipo? Empiezo a pensar que se te escapa el significado de alguna palabra que digo en referencia a esto y te da cosa preguntar aquí o buscar en internet.

Despiste : " #include <stdlib.h> "
Cita:

2)Veo que usas en algunos printf el formato para mostrar un tipo int %d cuando deberías usar el correspondiente "%ld" para long int.

Despiste.Es debido a que hice un código nuevo como copia del anterior, donde estaba el ordenamiento por burbuja, y en éste al incluir los máximos y mínimos como long con la cabezera #include <limits.h> que me indicastes se me escaparon los formatos de printf.
Cita:
3)El modo pedántico también me lanza un aviso de que en C90 no se pueden hacer declaraciones si no es al inicio de bloque como las siguientes:
Código:
    char nombre[80] = "NOM_ARCHIVO";
    char linea[81];

Lo tengo en modo pedántico y no me indico nada. No obstante, lo tendré en cuenta.
Cita:

Pero me gustaría saber si existe otra forma de evitarlo al leer el final del fichero , vamos que no sea con eof.


Sorancio escribió:
fgets devuelve NULL cuando llega al final del fichero Smile

Cita:
¿La has probado?

No. Lo intentaré nuevamente.
Cita:
5) La salida de tu programa me da errónea para la primera cadena de números:
Código:

2,1,6,3,5,6,8 <===la cambie y....

No existe mayor      No existe menor

Pues si que hay menor y es 1... y un mayor 8

Aquí estoy perdido. He puesto varios prinf, y max min no funciona con la primera línea. ? ? ? ?.
Cita:
6) Tal como llamas a la función fgets, con 80 caracteres reservados por la cadena linea ya hay suficiente( no hacen falta 81). Revisa como funciona la función fgets y verás que es así.

Que te voy a decir... amen.
Un saludo!
P.D ....Siento lo del mensaje, es algo en lo que no me había fijado hasta ahora.Lo tendré en cuenta.
Volver arriba
Pantalàimon_



Registrado: 17 Jul 2007
Mensajes: 1344

MensajePublicado: 12/08/2012 8:02 am
Título:

Si en codeblocks usas gcc prueba de añadire también "-ansi" a ver si así te saltan más errores. Se trata de una etiqueta para asegurarte que estás compilando en C90. Yo suelo usar el siguiente comando para compilar en gcc:

Código:
gcc -ansi -Wall -pedantic programa.c -o programa

De esta manera me avisa de muchos posibles problemas. Aunque si no recuerdo mal la etiqueta "-pedantic" llega a excederse en algunos casos y se queja de sentencias correctas, aunque potencialmente susceptibles de cometer algún error lógico.

Un saludo!
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 12/08/2012 1:37 pm
Título:

Para "empezar" he activado hasta 9 opciones en codeblocks , entre ellos el ISO, pedantic y pedantid-errors.
Otra cosa es "saber" interpretar los wanings, como el que salte en una declaración y el problema sea porque debe ir al principio del bloque - lo sé porque tú me lo indicaste.
Lo que más rabia me da es que con burbuja vaya O.K y con la detección de max-min no me "salte" la primera línea ... no encuentro la lógica, ya que con los printf que puse se "cargan" los elementos del array pero parece que pasan de los "IF".Quemaré pestañas.
Un saludo!
Volver arriba
leosan



Registrado: 19 Abr 2012
Mensajes: 730
Ubicación: GRAN CANARIA

MensajePublicado: 13/08/2012 1:37 pm
Título:

Sorancio escribió:
Vas a tener que ir haciendo pruebas Smile.

Era sólo cuestión de fijarse en double y cambiar los formatos del printf:
Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#define NOM_ARCHIVO  "C:\\ejercicio20.csv"
int main()
{
    int i,j,k;
    double temp,minimo=DBL_MIN ,maximo=DBL_MAX,max_global=DBL_MIN,min_global=DBL_MAX;
    double a[10]={0};
    char * pch;
    FILE* fichero;
    char linea[80];
    fichero = fopen(NOM_ARCHIVO, "wt");
    fputs("2.3,4,6,3,5,8.5\n", fichero);
    fputs("4,2.12,3\n", fichero);
    fputs("2,1,1,3,7.5,1,1", fichero);
    fclose(fichero);

    fichero = fopen(NOM_ARCHIVO, "rt");
    if (fichero == NULL)
        {
            printf("No existe el fichero!\n");
            return 1;
        }
    while (! feof(fichero))
        {
            fgets(linea, 80, fichero);
            puts(linea);
            pch = strtok (linea,",\n");
            i=j=0;
            while (pch != NULL)
              {
                a[i]=atof (pch);
                pch = strtok (NULL, ",\n");
                i++;
              }
                for (j=1; j< i; j++)
                    for (k=0; k< i-j; k++)
                        if (a[k] > a[k+1])
                        {
                            temp = a[k];
                           a[k] = a[k+1];
                            a[k+1] = temp;
                        }
            if (a[i-1]==a[i-2]) printf("\nNo existe mayor\t");
            else {
                maximo = a[i-1];
                if (maximo>max_global) max_global=maximo;
                printf("\nMayor : %g\t",maximo);
                }

            if (a[0]==a[1]) printf("\tNo existe menor\n");
            else {
                minimo = a[0];
                if (minimo<min_global) min_global=minimo;
            printf("\tMinimo : %g\n",minimo);
            printf ("\n\n");
                }
        }
    printf("\nMayor global: %g\t",max_global);
    printf("\tMinimo global: %g\n",min_global);
    fclose(fichero);
    return 0;
}
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 5 de 7Todas las horas están en GMT - 8 Horas
Ir a página Anterior  1, 2, 3, 4, 5, 6, 7  Siguiente

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com