Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Dani001 en 5 Marzo 2017, 16:57 pm



Título: Detectar linea en blanco en C
Publicado por: Dani001 en 5 Marzo 2017, 16:57 pm
Hola, Que funcion en C o de que manera puedo tetectar un espacio en blanco?
Por ejemplo, esta seria mi entrada que le mando desde la linea de comandos:

programa < entrada.in

AABCATFS
TTRTACAS

TRESSSAA
ASRTSOOA


Deberia leer solo las dos primeras y al detectar la linea en blanco cambiar a otra matriz para almacenar las otras dos restantes.
Gracias.


Título: Re: Detectar linea en blanco en C
Publicado por: MAFUS en 5 Marzo 2017, 17:15 pm
Busca una línea que únicamente contenga '\n'


Título: Re: Detectar linea en blanco en C
Publicado por: Dani001 en 5 Marzo 2017, 17:30 pm
Comprendo lo de '\n' pero  de que manera la puedo buscar?  estoy inciando en esto.
Gracias


Título: Re: Detectar linea en blanco en C
Publicado por: MAFUS en 5 Marzo 2017, 20:15 pm
Vale, entiendo. Algo que te va a gustar poco: C es un lenguaje de nivel medio y a diferencia de Java, C#, PHP, etc. debes aprender más de como funcionan los ordenadores por dentro, solo entonces sacarás todo el partido al lenguaje. Debes pensar que C fue creado para escribir el sistema operativo  UNIX y eso es trabajar con el hardware.

Dicho esto cuando en la línea de comandos haces COMANDO < ARCHIVO lo que haces es ejecutar el comando o programa y pasar el contenido del archivo al buffer de entrada estándar del comando. Desde tu punto de vista es como si alguien, una vez ejecutado el programa, hubiera escrito todo el contenido del archivo desde el teclado y debieras sacarlo.

En ce existe la función fgets que sirve para sacar una cadena de texto de un archivo, en tu caso el buffer de entrada (que es stdin).

Un posible inicio:
Código
  1. #include <stdio.h>
  2.  
  3. int main() {
  4.    char str[80] = {0};
  5.  
  6.    fgets(str, 80, stdin);
  7.    while(!feof(stdin)) {
  8.        /* Cambia la siguiente línea por tu detector
  9.          * de líneas vacías.
  10.          **/
  11.        printf("%s", str);
  12.  
  13.        fgets(str, 80, stdin);
  14.    }
  15. }


Título: Re: Detectar linea en blanco en C
Publicado por: integeroverflow en 5 Marzo 2017, 20:20 pm
tambien podrias leer caracter por caracter desde el archivo con la funcion fgetc(), y ir metiendo los caracteres uno por uno en un buffer llevando un contador, hasta encontrar el caracter '\n'.
cuando encuentres \n asumis que termino una linea, entonces copias el contenido del buffer (la linea) a donde la tengas que copiar, limpias el buffer, reinicias el contador y seguis leyendo caracteres.

el truco esta en que si encontrase el caracter \n, y el contador esta en 0 (es el primer caracter de la linea) asumis que la linea esta vacia y reinicias el buffer y el contador sin copiar nada, para seguir leyendo caracteres y repitiendo el proceso hasta EOF.


Título: Re: Detectar linea en blanco en C
Publicado por: Dani001 en 5 Marzo 2017, 21:43 pm
Excelente! Gracias por su ayuda ya quedo.


Título: Re: Detectar linea en blanco en C
Publicado por: Alberto n en 5 Marzo 2019, 03:09 am
Hola, Que funcion en C o de que manera puedo tetectar un espacio en blanco?
Por ejemplo, esta seria mi entrada que le mando desde la linea de comandos:

programa < entrada.in

AABCATFS
TTRTACAS

TRESSSAA
ASRTSOOA


Deberia leer solo las dos primeras y al detectar la linea en blanco cambiar a otra matriz para almacenar las otras dos restantes.
Gracias.

Como lo solucionaste, tengo un problema parecido...


Título: Re: [PARTIR EN PARRAFOS UN TEXTO ] Detectar linea en blanco en C
Publicado por: dijsktra en 7 Marzo 2019, 12:08 pm
Como lo solucionaste, tengo un problema parecido...

Todavia no lo ha resuelto.

Lo que dice MAFUS respecto a la redireccion de la entrada estandar en shell/UNIX (tambien en COMMAND/Microsoft) es cierto, pero va a ser dificil si no elevas la abstracción, de "caracter \n" a "linea vacia". Para eso te ayuda la función

Código:
#include <stdio.h>

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

Aquí va una propuesta, con una "durisima" formalización, de la que no estoy seguro al 100%.
IMPORTANTE: Segun mi criterio, el ultimo parrafo acaba en EOF, no en EOL.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <string.h> // strlen
  5.  
  6.  
  7. #define LINES_PER_FILE 1000
  8. #define LINES_PER_PARAGRAPH 100
  9. #define PARAGRAPH 100
  10. #define LENGTH_LINE 250
  11.  
  12. /*
  13.   Formal spec hard. Use line (not char) as main abstraction
  14.  
  15.   P : text[0..txtLns) of char[LENGTH_LINE];
  16.   Q : \forall i,j : 0 <= i <= j <= N and paragraph(V,i,j,N) :
  17.            let
  18.              M = emptyLines(V,0,i)
  19.            in
  20.              isCopy(Pgrphs,M,i,j) and PgrphLns[M]=(j-i)
  21.       txtPgrphs = min(1,N) + emptyLines(text,0,txtLns)
  22.  
  23.   where
  24.  
  25.      emptyLines(text,0,txtLns) = #i : 0 <=i <txtLns :empty(text[i])
  26.      paragraph(V,i,j,N) =
  27.                   i = max k : 0 <= k <=j and (k > 0 -> empty(text[k-1]) : k
  28.                   j = min k : i <= k <= N and (k < N -> empty(text[k]) : k
  29.      isCopy(Pgrphs,M,n,m) = \forall i : 0 <= i < m-n : Pgrphs[M][i]=text[n+i]
  30.  
  31. */
  32. void  text2paragraphs(const char text[][LENGTH_LINE],
  33.      const int txtLns,
  34.                      char pgrphs[PARAGRAPH][LINES_PER_PARAGRAPH][LENGTH_LINE],
  35.      int *txtPgrphs,
  36.      int pgrphLns[])
  37. {
  38.  int n;
  39.  for(*txtPgrphs=(txtLns>0), n=pgrphLns[0]=0;  n<txtLns;n++)  
  40.    if (strlen(text[n])>1)
  41.      strncpy(pgrphs[*txtPgrphs-1][pgrphLns[(*txtPgrphs-1)]++],text[n],LENGTH_LINE);
  42.    else
  43.      (*txtPgrphs)++;
  44.  return;
  45. }
  46.  
  47. int main(int argc, char *args[])
  48. {
  49.  char text[LINES_PER_FILE][LENGTH_LINE];
  50.  int txtLns,txtPgrphs;
  51.  char paragraphs[PARAGRAPH][LINES_PER_PARAGRAPH][LENGTH_LINE];
  52.  int pgrphLns[PARAGRAPH];
  53.  
  54.  char *line=NULL;
  55.  ssize_t read;
  56.  size_t len;
  57.  
  58.  // Input
  59.  txtLns = 0 ;
  60.  while ((read=getline(&line,&len,stdin))!=-1)
  61.      strncpy(text[txtLns++],line,LENGTH_LINE);
  62.  free(line);
  63.  
  64.  // Process
  65.  text2paragraphs(text,txtLns,paragraphs,&txtPgrphs,pgrphLns);
  66.  
  67.  // Output
  68.  printf("%d\n",txtPgrphs);
  69.  for (int i=0; i< txtPgrphs ; i++)
  70.    {
  71.      printf("(%d,%d)\n",i,pgrphLns[i]);
  72.      for (int j=0; j< pgrphLns[i] ; j++)
  73. printf("%d.%d\t%s",i,j,paragraphs[i][j]);
  74.    }
  75. }
  76.  
Ahora comprobamos con el siguiente soneto en castellano del insigne Garcilaso de la Vega (quitando acentos y usando algunas formas del siglo XVI). Fichero poema.txt

Código:
bash-2.04$ cat poema.txt
A Dafne ya los brazos le crecian
y en luengos ramos vueltos se mostraban;
en verdes hojas vi que se tornaban
los cabellos qu'el oro escurecian;

de aspera corteza se cubrian
los tiernos miembros que aun bullendo 'staban;
los blancos pies en tierra se hincaban
y en torcidas raices se volvian.

Aquel que fue la causa de tal danio,
a fuerza de llorar, crecer hacia
este arbol, que con lagrimas regaba.

Oh miserable estado, oh mal tamanio,
que con llorarla crezca cada dia
la causa y la razon por que lloraba!


Veamos la salida en shell/UNIX. La primera linea marca el  número de parrafos. Despues, por cada párrafo se da el número de orden , el total de líneas por parrafo, y cada línea enumerada dentro de su párrafo.

Código:
bash-2.04$ ./main < poema.txt
4
(1,4)
1.1 A Dafne ya los brazos le crecian
1.2 y en luengos ramos vueltos se mostraban;
1.3 en verdes hojas vi que se tornaban
1.4 los cabellos qu'el oro escurecian;
(2,4)
2.1 de aspera corteza se cubrian
2.2 los tiernos miembros que aun bullendo 'staban;
2.3 los blancos pies en tierra se hincaban
2.4 y en torcidas raices se volvian.
(3,3)
3.1 Aquel que fue la causa de tal danio,
3.2 a fuerza de llorar, crecer hacia
3.3 este arbol, que con lagrimas regaba.
(4,3)
4.1 Oh miserable estado, oh mal tamanio,
4.2 que con llorarla crezca cada dia
4.3 la causa y la razon por que lloraba!


Hmm...  :-\ Demasiada formalidad para un poema tan humano. ;) ;)