Bueno, al final he encontrado una manera de codear lo que quiero y optimizando muy mucho el tiempo aunque ocupando mas memoria. Este es el codigo:
Código C:
Ver original//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#define SIZEMAX 1024
typedef enum {
STR2INT_SUCCESS,
STR2INT_OVERFLOW,
STR2INT_UNDERFLOW,
STR2INT_INCONVERTIBLE
} str2int_errno;
int largoHash;
//---------------------------------------------------------------------------
void clean(void)
{
char a;
}
//---------------------------------------------------------------------------
void ObtenerRutas(char *pathOrigen1,char *pathOrigen2,char *pathDestino2,int *largoHash)
{
int largo;
printf("Introduce la ruta completa hacia el primer archivo:\n\t"); fgets(pathOrigen1
,SIZEMAX
,stdin
); if(pathOrigen1[largo-1]!='\n'){
clean();
printf("Ruta demasiado larga.\n"); }else{
pathOrigen1[largo-1]='\0';
}
printf("Introduce la ruta completa hacia el segundo archivo:\n\t"); fgets(pathOrigen2
,SIZEMAX
,stdin
); if(pathOrigen2[largo-1]!='\n'){
clean();
printf("Ruta demasiado larga.\n"); }else{
pathOrigen2[largo-1]='\0';
}
printf("Introduce la ruta completa para el archivo de salida:\n\t"); fgets(pathDestino2
,SIZEMAX
,stdin
); if(pathDestino2[largo-1]!='\n'){
clean();
printf("Ruta demasiado larga.\n"); }else{
pathDestino2[largo-1]='\0';
}
printf("Introduce el numero de caracteres del hash: "); }
//---------------------------------------------------------------------------
//Para convertir el parametro del largo del hash de cadena a entero
str2int_errno str2int(int *out, char *s, int base) {
char *end;
long l;
if (s
[0] == '\0' || isspace((unsigned char) s
[0])) return STR2INT_INCONVERTIBLE;
errno = 0;
if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
return STR2INT_OVERFLOW;
if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
return STR2INT_UNDERFLOW;
if (*end != '\0')
return STR2INT_INCONVERTIBLE;
*out = l;
return STR2INT_SUCCESS;
}
//---------------------------------------------------------------------------
int CheckParams(int nParametros, char *parametros[], char *pathOrigen1,char *pathOrigen2,char *pathDestino2,int *largoHash)
{
str2int_errno error_param_hash;
char mensaje[SIZEMAX];
if(nParametros == 5){
strcpy(pathOrigen1
,parametros
[1]); strcpy(pathOrigen2
,parametros
[2]); strcpy(pathDestino2
,parametros
[3]); error_param_hash=str2int(largoHash,parametros[4],10);
switch(error_param_hash){
case STR2INT_OVERFLOW:
strcpy(mensaje
,"STR2INT_OVERFLOW"); break;
case STR2INT_UNDERFLOW:
strcpy(mensaje
,"STR2INT_UNDERFLOW"); break;
case STR2INT_INCONVERTIBLE:
strcpy(mensaje
,"STR2INT_INCONVERTIBLE"); break;
}
if(error_param_hash != STR2INT_SUCCESS){
printf("Error en el parametro para el largo del hash. Error: %s\n",mensaje
); return -1;
}
if(*largoHash < 0){
printf("El valor asignado al largo del hash no puede ser menor que '0'.\nSi no hay hash ponga '0'.\n"); return -2;
}
}else if(nParametros > 1){
printf("parametros incorrectos.\n"); return -3;
}else{
ObtenerRutas(pathOrigen1,pathOrigen2,pathDestino2,largoHash);
}
return 0;
}
//---------------------------------------------------------------------------
void DescartarElemento(char **buffer,int pos,int *nElementos)
{
int i;
for(i=pos; i < *nElementos-1; i++){
buffer[i]=buffer[i+1];
}
(*nElementos)--;
}
//---------------------------------------------------------------------------
int CrearFicheroOrdenado(char **bufferFile1,char **bufferFile2,char *pathDestino,int largoHash,int nElementosBufferFile1,int nElementosBufferFile2)
{
FILE *destino=NULL;
int encontrado,noEncontrados=0;
int i,j,retval=0;
char **arrayAuxiliar;
destino
=fopen(pathDestino
,"w");
if(destino == NULL)
return -1;
printf("Ha comenzado el proceso. No cierre esta ventana hasta que termine el proceso.\n"); arrayAuxiliar
=malloc(nElementosBufferFile2
* sizeof(char**));
if(arrayAuxiliar == NULL){
return -2;
}
memcpy(arrayAuxiliar
,bufferFile2
,nElementosBufferFile2
* sizeof(char**));
for(i=0; i < nElementosBufferFile1; i++){
encontrado=0;
for(j=0; j < nElementosBufferFile2; j++){
if(strcmp(bufferFile1
[i
],arrayAuxiliar
[j
])==0){ encontrado=1;
break;
}
}
if(encontrado==1){
fputs(arrayAuxiliar
[j
],destino
); DescartarElemento(arrayAuxiliar,j,&nElementosBufferFile2);
}else{
noEncontrados++;
}
}
if(noEncontrados > 0)
retval=noEncontrados;
return retval;
}
//---------------------------------------------------------------------------
void LiberarMemoria(char **buffer,int nlines)
{
int index;
if(buffer != NULL){
for(index=0;index < nlines;index++)
buffer=NULL;
}
}
//---------------------------------------------------------------------------
char** CargarFicheroEnMemoria(char *path,int *nlines)
{
int largo;
char aux[SIZEMAX];
char **pbuffer,**paux;
FILE *origen;
*nlines=0;
if(origen != NULL){
pbuffer=NULL;
do{
fgets(aux
,SIZEMAX
,origen
); (*nlines)++;
paux
=(char**)realloc(pbuffer
,*nlines
*sizeof(char**)); if(paux != NULL){
pbuffer=paux;
pbuffer
[*nlines
-1]=(char*)malloc(sizeof(char*)*largo
); strcpy(pbuffer
[*nlines
-1],aux
); }else{
printf("No hay suficiente memoria disponible para volcar el archivo.\n"); LiberarMemoria(pbuffer,*nlines-1);
}
}
}
return pbuffer;
}
//---------------------------------------------------------------------------
/* funcion para comparar strings de C para qsort */
int cstring_cmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia
+largoHash
, *ib
+largoHash
); }
//---------------------------------------------------------------------------
//Se puede usar con parametros tambien
int main(int argc, char* argv[])
{
char pathOrigen1[SIZEMAX];
char pathOrigen2[SIZEMAX];
char pathDestino[SIZEMAX];
char **bufferFile1,**bufferFile2;
int nElementosFile1,nElementosFile2,retval;
if(CheckParams(argc,argv,pathOrigen1,pathOrigen2,pathDestino,&largoHash) == 0){
if((bufferFile1=CargarFicheroEnMemoria(pathOrigen1,&nElementosFile1)) > 0){
if((bufferFile2=CargarFicheroEnMemoria(pathOrigen2,&nElementosFile2)) > 0){
//Ordeno los elementos
qsort(bufferFile2
, nElementosFile2
, sizeof(char *), cstring_cmp
); retval=CrearFicheroOrdenado(bufferFile1,bufferFile2,pathDestino,largoHash,nElementosFile1,nElementosFile2);
switch(retval){
case 0:
printf("Proceso finalizado correctamente.\n"); break;
case -1:
printf("Proceso finalizado con errores.\n"); printf("No se pudo abrir el archivo \"%s\".\n",pathOrigen2
); break;
case -2:
printf("Proceso finalizado con errores.\n"); printf("No se pudo obtener memoria suficiente.\n"); break;
default:
printf("Proceso finalizado.\n"); printf("No se encontraron %d entradas en \"%s\".\n",retval
,pathOrigen2
); }
//Libero la memoria solicitada para guardar el archivo en ella
LiberarMemoria(bufferFile2,nElementosFile2);
}
LiberarMemoria(bufferFile1,nElementosFile1);
}
}
return 0;
}
//---------------------------------------------------------------------------