ayuda , guardar en un regsitro, inconvenientes

Iniciado por yeah_2796, 23 Enero 2018, 02:04 AM

0 Miembros y 2 Visitantes están viendo este tema.

yeah_2796

Hola a todos, verán tengo un incoveninete, tengo que leer desde un archivo que se llama entrada.in donde me daran varios de diferentes cosas, tiempo de llegada, scanners, impresoras, etc... valores los cuales tengo que guardar en un registro y bueno, use un arreglo de structs para eso, el asunto es que primero leo con fgetc cada numero caracter sin comas ni espacios en blancos,

despues el problema surge que al imprimir esos mismo valores que guardo, ocurre un problema ... creo que me imprime valores negativos entre cada valor y que tambien pareciera que en el ultimo valor, no se tomara un valor, como si no estuviera:

ejemplo del archivo:

1, 0, 1, 0, 0, 0, 0
1, 1, 2, 1, 0, 0, 1
3, 3, 6, 1, 0, 1, 2



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

struct list_entra {                       //registro con 7 campos
int tiempo_llegada;
   int prioridad;
   int procesa;
   int scanner;
   int impresora;
   int modem;
   int dvd;
}proentra [7] ;


int main (int argc, char *argv[]) {
int contaproceso= 0, i;                   //contador para saber en cual celda del arreglo de struct se guardará
int contcanti =0;                            //contador que uso para ver los diferentes campos del struct
char carac;

   FILE *archivo;
   archivo= fopen("listaprocesos.in", "r");

   if (archivo == NULL){
       printf ("error al abrir archivo \n");
       exit (1);
   }

   while (carac != EOF){                                                            //imprimo para ver si lee bien los caracteres que necesito
carac= fgetc (archivo);
       if (carac != '\n' && carac != ',' && carac != ' '){
printf ("%c\n", carac);
       }
       
       if (contcanti==0){ //lleno el registro y resto -48 para pasar de caracter a entero
proentra [contaproceso].tiempo_llegada= (int)(carac-48);
}else if (contcanti==1){
proentra[contaproceso].prioridad= (int)(carac-48);
}else if (contcanti==2){
proentra[contaproceso].procesa= (int)(carac-48);
}else if (contcanti==3){
proentra[contaproceso].scanner= (int)(carac-48);
}else if (contcanti==4){
proentra[contaproceso].impresora = (int)(carac-48);
}else if (contcanti==5){
proentra[contaproceso].modem= (int)(carac-48);
}else if (contcanti==6){
proentra[contaproceso].dvd= (int)(carac-48);
}
contcanti++;

if (contcanti==7){
contcanti=0;
contaproceso++;
}
   }
   
   for (i=0;i<contaproceso;i++){                                      //imprimo por pantalla
printf ("\n%d", proentra[i].tiempo_llegada );
printf ("\n%d", proentra[i].prioridad );
printf ("\n%d", proentra[i].procesa);
printf ("\n%d", proentra[i].scanner);
printf ("\n%d", proentra[i].impresora);
printf ("\n%d", proentra[i].modem);
printf ("\n%d", proentra[i].dvd);
}

   fclose (archivo);

   return 0;
}



y me muestra por consola esto:

1
0
1
0
0
0
0
1
1
2
1
0
0
1
3
3
6
1
0
1
2


1
-4
-16
0
-4
-16
1
-4
-16
0
-4
-16
0
-4
-16
0
-4
-16
0
-38
1
-4
-16
1
-4
-16
2
-4
-16
1
-4
-16
0
-4
-16
0
-4
-16
1
-38
3
-4
-16
3
-4
-16
6
-4
-16
1
-4
-16
0
-4
-16
1


podrían ayudarme, es una tarea que me mandaron, soy principiante en programación y he estado observando pero no lo logró ver el problema.

MAFUS

Todo lo que tienes hecho debe estar dentro del if(carácter !='\n'...
Cómo lo haces fuera, tu contador también cuenta esos caracteres y como lo usas para presentarlos en pantalla te devuelve lo que hay más allá de tus datos.

yeah_2796

vale gracias MAFUS, en seguida lo pruebo, supongo que cuando dices "todo debe estar del if (caracter!=\n)" hablas de todos los if y else if nada mas cierto?

MAFUS

Así es. El problema es que actualizas contaproceso y cintacanti fuera de eso, por tanto también suman las comas y los otros caracteres no deseados.

Por otra parte, y como consejo, todos esos if-else que se basan en un número entero los puedes sustituir por otra construcción que existe en C para ese propósito: switch-case. El código quedará más claro.
Aunque aún puedes ir un paso más allá con otra instrucción que te hará toda la captura de forma automática aprovechando que el formato del archivo siempre es el mismo y se considera, de por sí, bien formateado: la función fscanf. El grupo de de funciones scanf son muy potentes para estos trabajos pero para eso uno debe saber usar la cadena de control, aunque no es nada difícil.

dijsktra

Si sabes con garantías que el fichero de entrada tiene un formato definido...
¿ por qué no utilizar entrada-salida formateada? Es más fácil. te ahorras procesamiento de comas y espacios...

Aquí te dejo una idea. Tu la cojes y la adaptas a tus estructuras de registros, etc..  Yo he puesto fn, como abreviatura de "field"....


/*
  string formatted input-output
*/

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

#define MAX 1000

int main (void)
{
  FILE *f;
  int f0[MAX],f1[MAX],f2[MAX],
      f3[MAX],f4[MAX],f5[MAX],f6[MAX];
  int n,N;
 
  if (!(f = fopen("listaprocesos.in","r")))
    {
      perror("fopen");
      exit(EXIT_FAILURE);
    };
  for (N=0 ; fscanf(f,"%d, %d, %d, %d, %d, %d, %d\n",
    &f0[N],&f1[N],&f2[N],&f3[N],&f4[N],&f5[N],&f6[N])!=EOF; N++ );
 
  for (n=0 ; n<N ; n++)
    printf("%d, %d, %d, %d, %d, %d, %d\n",
   f0[n],f1[n],f2[n],f3[n],f4[n],f5[n],f6[n]);
  fclose(f);
  return 0;
}



Contenido de "listaprocesos.in"

1, 0, 1, 0, 0, 0, 0
1, 1, 2, 1, 0, 0, 1
3, 3, 6, 1, 0, 1, 2
2, 3, 1, 0, 0, 3, 2


Salida del programa.

1, 0, 1, 0, 0, 0, 0
1, 1, 2, 1, 0, 0, 1
3, 3, 6, 1, 0, 1, 2
2, 3, 1, 0, 0, 3, 2

Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)