elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [Función fscanf]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [Función fscanf]  (Leído 3,101 veces)
Apazche

Desconectado Desconectado

Mensajes: 1


Ver Perfil
[Función fscanf]
« en: 27 Diciembre 2017, 00:39 am »

Hola buenas, quiero saber la posición del cur de un archivo de texto a medida que leo caracteres con la función fscanf. Entonces, implemente lo siguiente ,en términos generales:

char c;
 
         
     while(!feof(fichero)){
        fscanf(fichero," %c",&c);
         printf("%c",c);
        printf("(%ld) ", ftell(fichero));
     }

En el archivo contiene los siguiente:

---------------------------------------------------------------------

supholasadkjholasad
adholadsa

---------------------------------------------------------------------

En el terminal se imprime:
---------------------------------------------------------------------

s(1) u(2) p(3) h(4) o(5) l(6) a(7) s(8) a(9) d(10) k(11) j(12) h(13) o(14) l(15) a(16) s(17) a(18) d(19) a(21) d(22) h(23) o(24) l(25) a(26) d(27) s(28) a(29) a(29)

---------------------------------------------------------------------

Mis preguntas son:
¿Por qué el carácter '\n' no lo imprime cuando lo lee?
El número 20 se lo salta al terminar de leer la primera línea, ¿Por qué?
fscanf lee '\n' ?  '\n' es un char, cierto?

Espero sus respuestas :D




En línea

fary


Desconectado Desconectado

Mensajes: 1.076



Ver Perfil WWW
Re: [Función fscanf]
« Respuesta #1 en: 28 Diciembre 2017, 15:16 pm »

Antes de nada quiero que sepas que mi teoría esta basada en mi mis conocimientos y puede ser erronea la explicación que te voy a dar.

He estado mirando en la documentación y no he encontrado respuesta, solo puedo comentarte que si quieres trabajar mejor con el fichero crees un puntero a los datos y no los vayas leyendo poco a poco. Puede que las funciones que estás usando para leer el archivo caracter a caracter supriman  los saltos de línea.

Por otra parte quiero que sepas que '\n' no es un solo caracter... No te lo explico, te lo muestro  :P

Código
  1. #include <stdio.h>
  2.  
  3. int main()
  4. {
  5.    char JmpLine[2] = {0};
  6.  
  7.    JmpLine[0] = 10;
  8.    JmpLine[1] = 13;
  9.    JmpLine[2] = 0;
  10.  
  11.    printf("Una linea %s Otra linea",JmpLine);
  12.  
  13.    return 0;
  14. }

saludos y espero resolver tu duda.

saludos.


En línea

Un byte a la izquierda.
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: [Función fscanf]
« Respuesta #2 en: 28 Diciembre 2017, 20:24 pm »

El retorno de carro depende del sistema operativo:
*nix: '\n'
Windows: '\n''\r'
MacOS: '\r'
En línea

dijsktra

Desconectado Desconectado

Mensajes: 110


Mr Edsger Dijsktra (Tribute to)


Ver Perfil
Re: [Función fscanf]
« Respuesta #3 en: 23 Abril 2018, 01:14 am »

Código
  1.  


Mis preguntas son:
¿Por qué el carácter '\n' no lo imprime cuando lo lee?
El número 20 se lo salta al terminar de leer la primera línea, ¿Por qué?
fscanf lee '\n' ?  '\n' es un char, cierto?

Espero sus respuestas :D


Como dices, "\n" es un carácter, pero la directiva de matching "%c", según el manual, salta todos los caracteres "white-space", (entendiendo estos como el spacio, el tablador, el fin de línea... todos los que responden a isspace(int c) ).
Si te fijas en la salida , salta del 19 al 21...

Otra aspecto tiene que ver con printf. Propimaente hablando, el caracter '\n' no es carácter imprimible, segun (isprint(c)) ,  sino de control iscntrl(c). En el caso de "\n" dicen que "debe" hacer un scrolling de 1 y empezar en la primera columna, no que imprima propiamente un caracter...



Una solución pasa por dejar usar las rutinas "high-level IO", los streams, a las de "low-level IO", los "file descriptors".

El incoveniente es que perdemos la funcionalidad de la rutina
Código
  1. long ftell(FILE *stream)

pero que podemos simular con

Código
  1. pos=lseek(fd,0,SEEK_CUR)

Por supuesto, para dar una salida formateada, debo volver a las rutinas "high-level" IO, como printf... Pero es un problema aparte de el de lectura read



Hay otro error, que ya muestro corregido, relatio a la función feof()... Esta función sólo tiene valores coherentes después de haber invocado la correspondiente fscanf, es decir, no puede anticipar si la cabeza lectora ha llegafo a fin de fichero..



Ahí va mi propuesta.

Código
  1. #include <stdlib.h> // exit()...
  2. #include <assert.h> // assert
  3. #include <unistd.h> // open,read,close (Low-level IO),
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h> // open,O_RDONLY...
  7. #include <stdio.h> //p printf
  8.  
  9.  
  10. #include <ctype.h> // isprint
  11.  
  12. int main()
  13. {
  14.  char c;
  15.  int n;
  16.  int fd;
  17.  const char *pattern="%d\t%c\t%d\n";
  18.  char row[80];
  19.  if (!(fd=open("texto.txt",O_RDONLY)))
  20.    {
  21.      perror("open");
  22.      exit(EXIT_FAILURE);
  23.    }
  24.  printf("ASCII\tPrint\tPos\n");
  25.  while((n=read(fd,&c,sizeof(char)))> 0)
  26.    {
  27.      assert(isascii(c));
  28.      if ((n=sprintf(row,pattern,c,isprint(c)?c:' ',lseek(fd,0,SEEK_CUR)))<0)
  29. {
  30.  perror("sprintf");
  31.  exit(EXIT_FAILURE);
  32. }
  33.      printf(row);
  34.    }
  35.  if (n==-1)
  36.    {
  37.      perror("read");
  38.      exit(EXIT_FAILURE);
  39.    }
  40.  close(fd);
  41.  exit(EXIT_SUCCESS);
  42. }
  43.  

Pasándole el fichero de texto propuesto
Código:
supholasadkjholasad
adholadsa

El programa arroja la salida siguiente: Cuando es imprimible, imprime su símbolo, cuando es de control, en su lugar, un espacio. (Los números que salen al principio los pone el codgo GeSHi del web, porque si no, perdía el formato de salida... un lío vamos)

Código
  1.  
  2. ASCII Print Pos
  3. 115 s 1
  4. 117 u 2
  5. 112 p 3
  6. 104 h 4
  7. 111 o 5
  8. 108 l 6
  9. 97 a 7
  10. 115 s 8
  11. 97 a 9
  12. 100 d 10
  13. 107 k 11
  14. 106 j 12
  15. 104 h 13
  16. 111 o 14
  17. 108 l 15
  18. 97 a 16
  19. 115 s 17
  20. 97 a 18
  21. 100 d 19
  22. 10 20
  23. 97 a 21
  24. 100 d 22
  25. 104 h 23
  26. 111 o 24
  27. 108 l 25
  28. 97 a 26
  29. 100 d 27
  30. 115 s 28
  31. 97 a 29
  32. 10 30
« Última modificación: 23 Abril 2018, 10:21 am por dijsktra » En línea

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

Desconectado Desconectado

Mensajes: 110


Mr Edsger Dijsktra (Tribute to)


Ver Perfil
Re: [Función fscanf]
« Respuesta #4 en: 20 Junio 2018, 15:42 pm »

Una solución pasa por dejar usar las rutinas "high-level IO", los streams, a las de "low-level IO", los "file descriptors".

El incoveniente es que perdemos la funcionalidad de la rutina
Código
  1. long ftell(FILE *stream)

Esto no es así necesariamente. Me corrijo a mí mismo. En high-level contamos con
Código
  1. int fgetc(FILE *stream);

que, sin buscar patrones como scanf, hace lo que queremos, conservando el ftell
El erroes es que en vez de scanf , la rutina qie había que haber utilizado era
fgetc

El nuevo programa, más sencillo queda:

Código
  1. #include <stdlib.h> // exit()...
  2. #include <assert.h> // assert
  3. #include <stdio.h> //p printf
  4. #include <ctype.h> // isprint
  5.  
  6. int main()
  7. {
  8.  char c;
  9.  int n;
  10.  FILE* fs;
  11.  const char *pattern="%d\t%c\t%d\n";
  12.  char row[80];
  13.  if (!(fs=fopen("texto.txt","r")))
  14.    {
  15.      perror("fopen");
  16.      exit(EXIT_FAILURE);
  17.    }
  18.  printf("ASCII\tPrint\tPos\n");
  19.  while((c=fgetc(fs))!=EOF)
  20.    {
  21.      assert(isascii(c));
  22.      if ((n=sprintf(row,pattern,c,isprint(c)?c:' ',ftell(fs)))<0)
  23. {
  24.  perror("sprintf");
  25.  exit(EXIT_FAILURE);
  26. }
  27.      printf(row);
  28.    }
  29.  if (c!=EOF)
  30.    {
  31.      perror("fgetc");
  32.      exit(EXIT_FAILURE);
  33.    }
  34.  fclose(fs);
  35.  exit(EXIT_SUCCESS);
  36. }
  37.  

Y la salida, como en el caso anterior, leyendo "texto.txt", queda
Código
  1.  
  2. ASCII Print Pos
  3. 115 s 1
  4. 117 u 2
  5. 112 p 3
  6. 104 h 4
  7. 111 o 5
  8. 108 l 6
  9. 97 a 7
  10. 115 s 8
  11. 97 a 9
  12. 100 d 10
  13. 107 k 11
  14. 106 j 12
  15. 104 h 13
  16. 111 o 14
  17. 108 l 15
  18. 97 a 16
  19. 115 s 17
  20. 97 a 18
  21. 100 d 19
  22. 10 20
  23. 97 a 21
  24. 100 d 22
  25. 104 h 23
  26. 111 o 24
  27. 108 l 25
  28. 97 a 26
  29. 100 d 27
  30. 115 s 28
  31. 97 a 29
  32. 10 30
En línea

Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema al usar la función fscanf para leer datos en un vector.
Programación C/C++
dvc 4 5,141 Último mensaje 15 Abril 2012, 22:16 pm
por dvc
Consulta fscanf leer nueva linea
Programación C/C++
casidus 7 4,612 Último mensaje 15 Febrero 2014, 12:16 pm
por casidus
Verificar que se lee con fscanf
Programación C/C++
bastri 4 3,246 Último mensaje 11 Junio 2015, 17:04 pm
por rir3760
feof y fscanf
Programación C/C++
fafafa01 3 2,984 Último mensaje 21 Mayo 2016, 08:27 am
por class_OpenGL
Fscanf en lenguaje C
Programación C/C++
grossgore 4 3,114 Último mensaje 28 Marzo 2018, 02:04 am
por grossgore
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines