2009-04-10 21 views
10

Estoy aprendiendo C de k & r como primer idioma, y ​​solo quería preguntar, si pensabas que este ejercicio se estaba resolviendo de la manera correcta, soy consciente de que probablemente no sea tan completo como como, pero quería puntos de vista, por lo que sabría que estoy aprendiendo C correctamente.K & R Capítulo 1 - Solución del ejercicio 22, ¿qué opinas?

Gracias

/* Exercise 1-22. Write a program to "fold" long input lines into two or 
* more shorter lines, after the last non-blank character that occurs 
* before then n-th column of input. Make sure your program does something 
* intelligent with very long lines, and if there are no blanks or tabs 
* before the specified column. 
* 
* ~svr 
* 
* [NOTE: Unfinished, but functional in a generic capacity] 
* Todo: 
* Handling of spaceless lines 
* Handling of lines consisting entirely of whitespace 
*/ 

#include <stdio.h> 
#define FOLD 25 
#define MAX 200 
#define NEWLINE '\n' 
#define BLANK ' ' 
#define DELIM 5 
#define TAB '\t' 

int 
main(void) 
{ 
    int line = 0, 
     space = 0, 
     newls = 0, 
      i = 0, 
      c = 0, 
      j = 0; 

    char array[MAX] = {0}; 

    while((c = getchar()) != EOF) { 
     ++line; 
     if(c == NEWLINE) 
      ++newls; 
     if((FOLD - line) < DELIM) { 
      if(c == BLANK) { 
       if(newls > 0) { 
        c = BLANK; 
        newls = 0; 
       } 
       else 
        c = NEWLINE; 
       line = 0; 
      } 
     } 
     array[i++] = c; 
    } 
    for(line = 0; line < i; line++) { 
     if(array[0] == NEWLINE) 
      ; 
     else 
      printf("%c", array[line]); 
    } 
    return 0; 
} 
+0

Tal vez deberías resolver tu propia tarea a ¿Significados? –

+1

@Phil: creo que lo hizo ... eso o el gran bloque de código fue descifrado. – Shog9

+0

@Phil, hay un amplio precedente para las personas que hacen preguntas sobre tareas siempre que hayan hecho un esfuerzo. Y realmente no sabes que es tarea, @svr puede autoaprendizaje. Esto es ciertamente mejor que los payasos que acaban de cortar y pegar la pregunta de su tarea textualmente. – paxdiablo

Respuesta

0

Un problema obvio es que se asigna estáticamente 'array' y nunca comprobar los límites de índice mientras se accede a ella. Desbordamiento de búfer esperando a suceder. De hecho, nunca restablece la variable i dentro del primer ciclo, por lo que estoy un poco confundido acerca de cómo se supone que debe funcionar el programa. Parece que está almacenando la entrada completa en la memoria antes de imprimirla envuelta en palabras.

Por lo tanto, sugerencias: combine los dos bucles e imprima la salida para cada línea que haya completado. Luego puede volver a usar la matriz para la próxima línea.

Ah, y mejores nombres de variables y algunos comentarios. No tengo idea de qué se supone que 'DELIM' debe hacer.

0

Parece (sin pruebas) que podría funcionar, pero parece algo complicado.

aquí hay algo de pseudocódigo para mi primer pensamiento

const int MAXLINE = ?? — maximum line length parameter 
int chrIdx = 0 — index of the current character being considered 
int cand = -1 — "candidate index", Set to a potential break character 
char linebuf[bufsiz] 
int lineIdx = 0 — index into the output line 
char buffer[bufsiz] — a character buffer 
read input into buffer 
for ix = 0 to bufsiz -1 
do  
    if buffer[ix] == ' ' then 
     cand = ix 
    fi 
    linebuf[lineIdx] = buffer[ix] 
    lineIdx += 1 
    if lineIdx >= MAXLINE then 
     linebuf[cand] = NULL — end the string 
     print linebuf 
     do something to move remnants to front of line (memmove?) 
    fi 
od 

Es tarde y sólo tenía un cinturón, por lo que podrían ser los defectos, pero muestra la idea general - cargar un buffer, y copiar el contenido de la buffer a un buffer de línea, haciendo un seguimiento de los posibles puntos de ruptura. Cuando te acerques al final, usa el punto de interrupción.

7

estoy seguro de que en la pista rigth, pero algunos consejos para facilitar la lectura:

  • comentario tus cosas
  • nombre de las variables correctamente y por lo menos dar una descripción si se niega
  • ser consecuentes , algunos ifs de una sola línea y otros no. (En mi humilde opinión, siempre use {} por lo que es más fácil de leer)
  • la sentencia if en el último bucle para puede ser el mejor, al igual que

    if(array[0] != NEWLINE) 
    { 
     printf("%c", array[line]); 
    } 
+0

@Mafti: voy a seguir todas sus sugerencias; era un primer borrador, solo para ver si entendía el truco, de una manera ligeramente elegante. Estás en lo cierto acerca de la última secuencia de ciclo, probablemente debería haber sabido escribirla como tal. Gracias –

2

eso no es bueno en mi humilde opinión.

Primero, no hace lo que se le pidió. Se suponía que debía encontrar el último espacio en blanco después de un espacio no en blanco antes del límite de la línea de salida. Su programa ni remotamente intenta hacerlo, parece esforzarse por encontrar el primer espacio en blanco después de (margen - 5) caracteres (¿de dónde vino el 5? ¿Y si todas las palabras tuvieran 9 letras?). Sin embargo, tampoco lo hace, debido a su manipulación con la variable newls. Además, esto:

for(line = 0; line < i; line++) { 
    if(array[0] == NEWLINE) 
     ; 
    else 
     printf("%c", array[line]); 
} 

es probablemente incorrecto, porque se comprueba una condición que nunca cambia a lo largo del ciclo.

Y, por último pero no menos importante, almacenar todo el archivo en un buffer de tamaño fijo no es bueno, debido a dos razones:

  • el buffer está obligado a desbordamiento en archivos grandes
  • incluso si nunca se desbordará, a la gente todavía no le gustaría que usted guarde, por ejemplo. un archivo de gigabyte en la memoria solo para cortarlo en trozos de 25 caracteres

Creo que deberías comenzar de nuevo, reconsiderar tu algoritmo (incluyendo casos de esquina), y solo después de eso, comenzar a codificar. Le sugiero:

  • proceso el archivo línea por línea (es decir las líneas de salida)
  • tienda de la línea en un buffer lo suficientemente grande como para mantener la línea de salida más grande
  • búsqueda del personaje que romperse en en el búfer
  • luego imprimirlo (pista: se puede interrumpir la cadena con '\ 0' e imprimir con printf("%s", ...)), copiar lo que no imprimió al inicio de la memoria intermedia, proceder de esa
Cuestiones relacionadas