Ver Mensaje Individual
  #7 (permalink)  
Antiguo 27/04/2016, 06:49
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Proyecto de C

Nombres de variables

¿a tí te parece que el nombre arch sobreentiende que sirve para gestionar el fichero de entrada? ¿y fp el de salida?

A mi al menos no. Te recomiendo utilizar nombres que sean significativos si no quieres volverte loco en cuanto el programa crezca un poco.

Buffers

Código C:
Ver original
  1. char linea[150];
  2. while (fscanf (arch, "%s", linea) != EOF) {

Por lo que has puesto en tu primer mensaje el fichero de entrada tiene líneas de longitud aleatoria... eso si no resulta que está todo en una sola línea.

¿Qué sucede si intentas almacenar en linea más de 149 caracteres? En el mejor de los casos que el programa fallará y se cerrará. En el peor de los casos seguirá funcionando pero habrás pisado memoria que no te corresponde, luego su comportamiento a partir de ese momento será errático.

Comparación de cadenas

Código C:
Ver original
  1. if (compTexto(linea,token1)){

En línea con el apartado anterior. En el fichero de entrada no veo que los tokens sean los únicos elementos en una línea luego esa comparación va a fallarte siempre.

Ideas
Si sabes que el fichero de entrada tiene un formato específico crea funciones para leerlo. Por ejemplo, sabes que el fichero se estructura en tokens y que los tokens empiezan con '<', pues para empezar yo crearía una función que me permitiese buscar caracteres en una cadena. Algo del tipo:

Código C:
Ver original
  1. char* BuscarEnCadena(char* ptr, char caracter);

Donde ptr sería un puntero a una cadena de texto y en caracter indicas el item que quieres buscar.

Es importante que te devuelva un puntero a la posición del caracter o NULL si no hay más ocurrencias.

Vale, ya has localizado el posible inicio de un token (digo posible porque nada impide poner ese caracter entre medias). Ahora habría que averiguar qué token es.

Lo más limpio es usar un enumerado y una función:

Código C:
Ver original
  1. typedef enum
  2. {
  3.   Ninguno,
  4.   Mensajes,
  5.   FinMensajes
  6.   Mensaje,
  7.   FinMensaje
  8.   Destinatario,
  9.   FinDestinatario
  10.   Texto
  11.   FinTexto
  12. } Tokens;
  13.  
  14. Tokens CheckToken(char* ptr);

¿Por qué usar un enumerado?
  • Por que el código que queda es más limpio.
  • Porque los enumerados se pueden comparar con ==
  • Porque los enumerados se pueden usar en una sentencia switch
  • Porque si te equivocas al escribir un enumerado el compilador te avisa con un error

La función simplemente tendría que verificar si ptr contiene alguno de los tokens y devolvería el valor del enum que correspondiese.

Recapitulando, ya puedes localizar caracters determinados en una cadena y puedes comprobar el tipo de token. ¿Qué tal una función para extraer el contenido entre dos punteros?

Código C:
Ver original
  1. void CopiaString(char* inicio, char* fin, char* destino);

La idea es la siguiente:
  • Localizar dónde termina el token Destinatario
  • Localizar dónde empieza el token /Destinatario
  • Copiar lo que hay entre medias, que al fin y al cabo es la información que te interesa.
  • Repetir los pasos anteriores para Texto

Y con esto prácticamente ya tendrías la lectura del fichero de entrada lista.

Para el fichero de salida tienes que partir el mensaje mientras exceda de 160 caracteres. Como no creo que te apetezca pegarte con memoria dinámica que tal una función tal que:

Código C:
Ver original
  1. int PartirString(char* inicio, char* destino, int longitud);

La función podría devolver un 1 si aun queda cadena por trocear y 0 en caso contrario. Esta opción te permite saber cuándo parar.

La función podría usar una variable estática interna para no tener que actualizar el puntero inicio en cada llamada... algo así:

Código C:
Ver original
  1. char buff[10];
  2. char* textoOriginal = "Hola";
  3. int res = PartirString(textoOriginal,buff,1); // buff = "H", res=1
  4. res = PartirString(NULL,buff,1); // buff = "o", res=1
  5. res = PartirString(NULL,buff,1); // buff = "l", res=1
  6. res = PartirString(NULL,buff,1); // buff = "a", res=0

Cómo declarar la variable estática... pues algo así:

Código C:
Ver original
  1. int PartirString(char* inicio, char* destino, int longitud)
  2. {
  3.   static char* ptr = NULL;
  4.  
  5.   if( inicio != NULL )
  6.     ptr = inicio;
  7.  
  8.   // A partir de aquí trabajas únicamente con ptr
  9.   // ...
  10. }

Y bueno, con esto prácticamente ya tendrías casi todo el programa hecho... no se me ocurren más funciones que vayas a necesitar para terminar el trabajo.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 27/04/2016 a las 09:47