C/Visual C - Manejo de ficheros en C

 
Vista:
sin imagen de perfil

Manejo de ficheros en C

Publicado por Daniel (4 intervenciones) el 13/10/2014 21:40:02
Tengo que desarrollar el siguiente algoritmo:

Haga la función llamada To_Upper() que toma el archivo texto de entrada y lo
convierte a mayúsculas.

No tenía idea de manejo de ficheros en c, investigue y he logrado hacer varias cosas pero no modificar el archivo en si, sé que existe la función toupper pero de ahí no sabría como usarla para lleva a cabo esto, agradezco su pronta ayuda, creerá que se podría con la función fwrite o algo por el estilo, esto debe ser implementado en ficheros .txt
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 14/10/2014 18:28:23
El código no esta copiado de ningún lado, lo he creado en 30 minutos, por ese motivo puedo responderte si tienes alguna duda..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#define SIZE_BUFFER 8192
 
static int ReadFile(FILE *fp, char *buf, int size);
static int WriteFile(FILE *fp, char *buf, int size);
static FILE *SetFile(char *patch);
 
int ReadFile(FILE *fp, char *buf, int size) {
	int readsize = 0;
 
	readsize = fread(buf, sizeof(char), SIZE_BUFFER, fp);
	if ( size == 0){
		printf("%s \n", "Fin lectura");
		return -1;
	}
	printf("Lectura = %d \n", readsize);
	return readsize;
}
 
int WriteFile(FILE *fp, char *buf, int size) {
	int writesize = 0;
 
	fseek(fp, -SIZE_BUFFER, SEEK_CUR);
 
	writesize = fwrite(buf , sizeof(char) , size , fp );
	printf("escritura = %d \n", writesize);
 
	if (writesize < SIZE_BUFFER){
		printf("%s \n", "Fin escritura");
		return -1;
	}
	if (writesize == 0){
		printf("%s \n", "Error fwrite");
		return -2;
	}
 
	return writesize;
}
 
FILE *SetFile(char *patch){
	FILE *fp;
	fp = fopen( patch, "rw+" );
	if(fp == NULL){
		printf("Error , fichero no en ruta indicada\n");
		exit(0);
	}
	return fp;
}
int main(void){
 
	FILE *fp;
	char *buffer;
	char *p;
	int size = 0;
	int raw = 0;
	int write = 0;
	int pos =0;
	char c;
 
	buffer = malloc(SIZE_BUFFER);
	fp = SetFile("./prueba");
 
	for(;;){
		if (raw == size ){
			if (pos > 0){
				write = WriteFile(fp,buffer,pos);
				if (write < 0)
					break;
			}
			size = ReadFile(fp,buffer,SIZE_BUFFER);
			if (size <= 0)
				break;
			pos = raw = 0;
			p = buffer;
		}
		c = p[raw];
		if( (c > 96 ) && c < 123) {
			 p[raw] = c - 'a' + 'A';
		}
		raw++;
		pos++;
	}
 
	fclose(fp);
	free(buffer);
	return 0;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 14/10/2014 19:10:50
La prisas no son buenas compañeras.

No se actualiza los ultimos bytes del fichero, la función WriteFile debe quedar de esta manera
se cambia fseek(fp, -SIZE_BUFFER, SEEK_CUR);

por fseek(fp, -size, SEEK_CUR);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int WriteFile(FILE *fp, char *buf, int size) {
	int writesize = 0;
 
	fseek(fp, -size, SEEK_CUR);
 
	writesize = fwrite(buf , sizeof(char) , size , fp );
	printf("escritura = %d \n", writesize);
 
	if (writesize < SIZE_BUFFER){
		printf("%s \n", "Fin escritura");
		return -1;
	}
	if (writesize == 0){
		printf("%s \n", "Error fwrite");
		return -2;
	}
 
	return writesize;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 15/10/2014 19:31:57
Otro ejemplo, más simple que el anterior.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#define SIZE_BUFFER 8192
 
static int ReadFile(FILE *fp, char *buf, int size);
static int WriteFile(FILE *fp, char *buf, int size);
static FILE *SetFile(char *patch);
static char UperFile(char c);
 
 
int ReadFile(FILE *fp, char *buf, int size) {
	int readsize = 0;
 
	readsize = fread(buf, sizeof(char), size, fp);
	if ( readsize == 0){
		printf("%s \n", "Fin lectura");
		return -1;
	}
	printf("Lectura = %d \n", readsize);
	return readsize;
}
 
int WriteFile(FILE *fp, char *buf, int size) {
	int writesize = 0;
 
	fseek(fp, -size, SEEK_CUR);
 
	writesize = fwrite(buf , sizeof(char) , size , fp );
	printf("escritura = %d \n", writesize);
 
	if (writesize < SIZE_BUFFER){
		printf("%s \n", "Fin escritura");
		return -1;
	}
	if (writesize == 0){
		printf("%s \n", "Error fwrite");
		return -2;
	}
 
	return writesize;
}
 
FILE *SetFile(char *patch){
	FILE *fp;
	fp = fopen( patch, "rw+" );
	if(fp == NULL){
		printf("Error , fichero no en ruta indicada\n");
		exit(0);
	}
	return fp;
}
 
char UperFile(char c){
	char uper;
 
	if( (c > 96 ) && c < 123) {
		uper = c - 'a' + 'A';
		return uper;
	}
	return c;
}
 
 
int main(void){
	FILE *fp;
	char *buffer;
	char *p;
	int size = 0;
	int raw = 0;
	int write = 0;
	char c;
 
	buffer = malloc(SIZE_BUFFER);
	fp = SetFile("./prueba");
 
	while(1){
		size = ReadFile(fp,buffer,SIZE_BUFFER);
		p = buffer;
		raw = 0;
		if (size <= 0)
			break;
		for (; raw < size; raw++){
			c = p[raw];
			p[raw] = UperFile(c);
		}
		write = WriteFile(fp,buffer,size);
			if (write < 0)
				break;
	}
 
	fclose(fp);
	free(buffer);
	return 0;
 
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 15/10/2014 21:10:33
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
*Este ejemplo posibilita el intercambio de diferente formas
*de lectura e escritura y gestionar el bloque de dato en CONJUNTO
*usando funciones a punteros.
*/
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
typedef int (*FpReadFile)(FILE *, char *, int);
typedef int (*FpWriteFile)(FILE *, char*, int);
typedef int (*FpSetBuffer)(char*, int);
typedef struct DataFile{
	FpReadFile FreadFile;
	FpWriteFile FwriteFile;
	FpSetBuffer FsetBuffer;
}DataFile;
 
#define SIZE_BUFFER 8192
 
static int ReadFile(FILE *fp, char *buf, int size);
static int WriteFile(FILE *fp, char *buf, int size);
static FILE *SetFile(char *patch);
static int SetComma(char *buff, int size);
static int  SetUper(char *buff, int size);
 
int ReadFile(FILE *fp, char *buf, int size) {
	int readsize = 0;
 
	readsize = fread(buf, sizeof(char), size, fp);
	if ( readsize == 0){
		printf("%s \n", "Fin lectura");
		return -1;
	}
	printf("Lectura = %d \n", readsize);
	return readsize;
}
 
int WriteFile(FILE *fp, char *buf, int size) {
	int writesize = 0;
 
	fseek(fp, -size, SEEK_CUR);
 
	writesize = fwrite(buf , sizeof(char) , size , fp );
	printf("escritura = %d \n", writesize);
 
	if (writesize < SIZE_BUFFER){
		printf("%s \n", "Fin escritura");
		return -1;
	}
	if (writesize == 0){
		printf("%s \n", "Error fwrite");
		return -2;
	}
 
	return writesize;
}
 
FILE *SetFile(char *patch){
	FILE *fp;
	fp = fopen( patch, "rw+" );
	if(fp == NULL){
		printf("Error , fichero no en ruta indicada\n");
		exit(0);
	}
	return fp;
}
 
int SetUper(char *buff, int size){
	char *p;
	char *c;
	int i;
 
	c = p = buff;
 
	for (i = 0; i < size; i++,p++){
		c = p;
		if( (*c > 96 ) && *c < 123) {
			*p = *c - 'a' + 'A';
		}
	}
 
	return 1;
}
 
int SetComma(char *buff, int size){
	char *p;
	char *c;
	int i;
 
	c = p = buff;
 
	for (i = 0; i < size; i++,p++){
		c = p;
		if( *c == '.') {
			*c = ',';
		}
	}
 
	return 1;
}
 
 
DataFile *InitDataFile(void){
	DataFile *dtf;
 
	dtf = malloc(sizeof(DataFile));
	dtf->FwriteFile = WriteFile;
	dtf->FreadFile = ReadFile;
	dtf->FsetBuffer = SetUper;
	/*dtf->FsetBuffer = SetComma;*/
	return dtf;
}
 
int main(void){
	FILE *fp;
	char *buffer;
	int size = 0;
	int write = 0;
	DataFile *dtf;
 
	buffer = malloc(SIZE_BUFFER);
	fp = SetFile("./prueba");
	dtf = InitDataFile();
 
	for(;;){
		size = dtf->FreadFile (fp,buffer,SIZE_BUFFER);
		if (size <= 0)
			break;
		dtf->FsetBuffer(buffer,size);
		write = dtf->FwriteFile(fp,buffer,size);
		if (write < 0)
			break;
	}
 
	fclose(fp);
	free(buffer);
	free(dtf);
 
	return 0;
 
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Tom (619 intervenciones) el 16/10/2014 10:45:27
¿ No nos complicamos mucho la vida ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FILE* fdin = fopen("prueba.txt", "r");
 
	if(fdin) {
		FILE* fdout = fopen("prueba.txt", "r+");
 
		if(fdout) {
			int c;
			while((c = fgetc(fdin)) != EOF) {
				fputc(toupper(c), fdout);
			}
			fclose(fdout);
		} else {
			perror("prueba.txt");
		}
 
		fclose(fdin);
	} else {
		perror("prueba.txt");
	}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por chema (234 intervenciones) el 16/10/2014 16:54:07
Estimado Toni complicarse la vida es sólo conocer una manera de hacer las cosas,

"Cuando la única herramienta que tienes es un martillo, todo problema comienza a parecerse a un clavo"

http://es.wikipedia.org/wiki/Martillo_de_oro

Existe una diferencia fundamental, el código que yo propongo trabaja en bloques de 1 K , 8192, la lectura es secuencial y de un tamaño ajustado al cache de lectura de un disco duro normal, es decir la aguja del disco leería como si fuera el segundero de un reloj, sin saltos , y eso Toni,, en ficheros de gran tamaño redunda en menor tiempo de lectura.

Otra ventaja de trabajar en bloques es el la copia, se puede distribuir bloques de 8192 y copiarse rápidamente.

Otra ventaja es que según que casos se pueden ordenar el contenido de los bloques y guardarlos ordenados en diferentes ficheros.

Otra ventaja de trabajar en bloques es que dentro de un mismo fichero puedo ordenar bloques

Otra ventaja es que un bloque de 8192 es múltiplo de 4, lo cual hace posible leer el bloque en 4 o multiplos de 4, tipos int o estructuras multiplos de 4. es decir puedo guardar char como int y leerlos de forma natural.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 16/10/2014 17:49:11
Toni espero que te halla quedado claro la diferencia entre técnica , y complicación gratuita , el código que consideras complicado contiene técnica con un fin determinado.



Estoy harto de profesores de Universidad, Profesorers que dan clases de C, Jakers, ingenieros, y supuestos programadores profesionales que no salen del scanf,,strtock,fgetc, snprintf y similares, además de cortar y pegar código malo.

La diferencia entre la mediocridad y la excelencia es la técnica.

PD otra ventaja de trabajar en bloques es evitar un exceso de llamadas a funciones, que repercuten seriamente en el tiempo de terminación de la tarea.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Tom (619 intervenciones) el 16/10/2014 18:35:23
Ufff ... lo que cuentas parece de los tiempos de MS/DOS y FAT.

Solamente "por culturilla", te recuerdo que la librería estándar de C, al usar streams (FILE*) ya crea buffers adicionales de E/S de manera interna. Puedes modificar ese comportamiento, pero no veo que uses setvbuf() ni nada así.

Si te paras a pensar (y olvídate de los bloques de 8 Kb, que hace mucho tiempo que eso es un concepto a olvidar) lo que tú estás haciendo es añadir una copia más de memoria:

Cache del disco (en el hardware) -> Buffer del S.O.(en el kernel) -> Buffer de libc (en tu programa) -> Buffer de tu programa.

Y, en mi opinión, c no es precisamente un martillo, más bien una caja de herramientas completa :D
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por chema (234 intervenciones) el 16/10/2014 18:56:10
Se nota que no trabajas con ficheros de gran tamaño y tampoco te as parado a medir lo tiempos de respuesta.

Crea un fichero de 500 megas, lo lees y escribes con el código expuesto y presenta la diferencia de tiempo y después me hablas de streams (FILE*) librería estándar y lo que quieras.

Y también podrías verificar los millones de llamadas a funciones que se realizan de una forma contra unos pocos miles de la otra manera.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Tom (619 intervenciones) el 16/10/2014 19:45:11
Sí, eso estaba haciendo. Ya sacaré los resultados (en linux -no tengo el gcc en win- que usa además cachés) si tengo tiempo de terminarlo :)
Y, por cierto, que yo ni afirmo ni niego que usar buffers adicionales acelere o retarde la E/S ... como no todos los problemas son clavos, cada uno requiere su herramienta para solucionarlo ;)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 16/10/2014 22:08:40
Bienvenido al club de los creyentes que les gusta progresar, así se hacen las cosas , se comprueban de forma objetiva.

El resultado en tiempo divídelo por el tamaño del fichero , el numero de megas por segundo es otra forma de medir el rendimiento que ofrece un resultado mas "comprensible" que milisegundos.

Si te interesa el tema cambia toupper por una función dentro de la misma funión tipo f( (*c > 96 ) && *c < 123) , verás la diferencia en rendimiento entre llamar millones de veces una función que puedes implementar con código dentro de la misma función.
'
El cache de linux es una maravilla, pero para pruebas es muy engañoso, un resultado más realista se consigue ejecutando el programa nada más iniciar el sistema, donde todavía no existen cache.

La diferencia será mucho más de un segundo te lo garantizo ( a no ser que hagas trampas jejeje), pero aunque fuera un segundo , mil milesimas es mucho tiempo en términos de comparación.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Tom (619 intervenciones) el 17/10/2014 12:16:06
En Linux es difícil probar estas cosas, efectivamente, por los cachés que mantiene el kernel.
He probado al menos 6 métodos de hacer lo que se pide: simplemente tomar un fichero y convertir su contenido a mayúsculas con toupper().
He creado un fichero de 500 MiB. Todos los métodos que he probado dan tiempos de 2 a 4 segundos (excepto la primera vez, cuando aún no se ha cacheado el fichero), valores que podrían cambiar muchísimo en cualquier otra máquina o situación.

El método simple de fgetc() -> fputc() es de los más lentos, del orden de un 10% más lento que la media. Pero he de hacer notar que aunque el tiempo real (usuario + sistema) es mayor en un 10% o 20%, el tiempo de sistema es muchísimo menor, del orden de 1/3 de la media (hablo de valores como 0.077s frente a 0.272s). O sea, el método más rápido puede ser muy, muy sensible a la carga de trabajo de la máquina y así.

Además, no he probado las rutinas "low level", o sea open() y read() ... lo haré por curiosidad.

Pego el código de los dos métodos más rápidos (prácticamente tiempos iguales en todas las pruebas) en mi PC (los resultados no son, para nada, extrapolables a cualquier otra máquina; mmap puede incluso no funcionar en Win):

--- El método más rápido (mmap) en mi PC, tras ejecutarlo 10 veces con un fichero de 500MiB:
- De media se obtienen estos tiempos (aproximadamente):
Total: 2 s
Usuario: 1,7 s
Sistema: 0.3 s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
 
/* */
void usage(char pname[]) {
	fprintf(stderr, "Usage: %s <fichero>\n", pname);
	exit(1);
}
 
/* */
int main(int argc, char* argv[]) {
	if(argv[1]) {
		int fd = open(argv[1], O_RDWR);
 
		if(fd >= 0) {
			int		i, len;
			struct stat	st;
			char	*buffer;
 
			if(!fstat(fd, &st)) {
				if((buffer = (char*)mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) != NULL) {
					for(i = 0; i < st.st_size; i++) {
						buffer[i] = (char)toupper(buffer[i]);
					}
					munmap(buffer, st.st_size);
				} else {
					perror("mmap");
				}
			} else {
                                perror("fstat");
                        }
			close(fd);
		} else {
			perror(argv[1]);
		}
	} else {
		usage(argv[0]);
	}
}

--- El otro método más rápido (fread, fseek, fwrite) en mi PC, tras ejecutarlo 10 veces con un fichero de 500MiB:
- De media se obtienen estos tiempos (aproximadamente):
Total: 2,1 s
Usuario: 1,7 s
Sistema: 0.4 s
- Curiosamente, aunque la media es similar, el tiempo más pequeño obtenido es muy bajo: 1,3 s (lógicamente, el tiempo mayor también es bastante más alto que la media).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* */
void usage(char pname[]) {
	fprintf(stderr, "Usage: %s <fichero>\n", pname);
	exit(1);
}
 
/* */
int main(int argc, char* argv[]) {
	if(argv[1]) {
		FILE *fin = fopen(argv[1], "r+");
		if(fin) {
			char	buffer[1024];
			int		i, len;
 
			while((len = fread(buffer, 1, 1024, fin)) > 0) {
				for(i = 0; i < len; i++) {
					buffer[i] = (char)toupper(buffer[i]);
				}
				fseek(fin, SEEK_CUR, -len);
				fwrite(buffer, 1, len, fin);
			}
			fclose(fin);
		} else {
			perror(argv[1]);
		}
	} else {
		usage(argv[0]);
	}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Tom (619 intervenciones) el 17/10/2014 13:04:02
Curioso. Al hacer las cosas "bien", asegurando que los datos se envían al disco, la cosa cambia. La mayoría de los métodos varían muy poco en tiempo, pero el 2º método que he puesto (fread -> fseek -> fwrite) ha sufrido mucho, incrementando su tiempo medio de ejecución en un 50% (de 2 a 3 seg):

while((len = fread(buffer, 1, 1024, fin)) > 0) {
for(i = 0; i < len; i++) {
buffer[i] = (char)toupper(buffer[i]);
}
fseek(fin, SEEK_CUR, -len);
fwrite(buffer, 1, len, fin);
}
fflush(fin);
fsync(fileno(fin));
fclose(fin);
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por chema (234 intervenciones) el 17/10/2014 17:34:22
EL código actualiza un bloque si otro no fseek(fin, SEEK_CUR, -len); , así corre mucho, va "dopado" y es casi un segundo más lento que el código que yo propongo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* */
void usage(char pname[]) {
	fprintf(stderr, "Usage: %s <fichero>\n", pname);
	exit(1);
}
 
/* */
int main(int argc, char* argv[]) {
	if(argv[1]) {
		FILE *fin = fopen(argv[1], "r+");
		if(fin) {
			char	buffer[1024];
			int		i, len;
 
			while((len = fread(buffer, 1, 1024, fin)) > 0) {
				for(i = 0; i < len; i++) {
					buffer[i] = (char)toupper(buffer[i]);
				}
				fseek(fin, SEEK_CUR, -len);
				fwrite(buffer, 1, len, fin);
			}
			fclose(fin);
		} else {
			perror(argv[1]);
		}
	} else {
		usage(argv[0]);
	}
}



int WriteFile(FILE *fp, char *buf, int size) {
int writesize = 0;

fseek(fp, -size, SEEK_CUR);
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 17/10/2014 18:11:37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* */
int main(int argc, char* argv[]) {
	if(argv[1]) {
		FILE *fin = fopen(argv[1], "r+");
		if(fin) {
			char	buffer[1024];
			int		i, len;
 
			while((len = fread(buffer, 1, 1024, fin)) > 0) {
				for(i = 0; i < len; i++) {
					buffer[i] = (char)toupper(buffer[i]);
				}
/* colocamos la función fseek de forma que actualize correctamente */
				fseek(fin,  -len, SEEK_CUR);
				fwrite(buffer, 1, len, fin);
			}
			fclose(fin);
		} else {
			perror(argv[1]);
		}
	} else {
		usage(argv[0]);
	}
}


Ejecutado contra un fichero de 457.8 megas.

en FUJITSU Server PRIMERGY TX300 con dos discos duros en raid que ofrecen una velocidad de lectura (teorica y maxima) de 320 megas segundo.

La versión modificada para que actualice. todas las lineas.

[chema@localhost csv]$ time ./b ./prueba

real 0m2.461s
user 0m1.596s
sys 0m0.862s

la versión que yo propongo.
[chema@localhost csv]$ time ./a

real 0m1.112s
user 0m1.060s
sys 0m0.216s

Probado varias veces la diferencia oscila entre 1, 5 y 2 segundos a favor de la versión que yo propongo.

Lo interesante de todo esto, no es quien tenga razón , eso es lo de menos, la moraleja de todos esto es la técnica.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por ricardo (1 intervención) el 17/10/2014 19:52:56
Tengo un problema en la ejecución de esta rutina, ojalá puedan ayudarme:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#define _CRT_SECURE_NO_DEPRECATE
 
#include <iostream>
#include <conio.h> //cout cin
#include <stdio.h> //maneja archivos
// #include <dos.h>
#include <stdlib.h>
#include <ctype.h>
#include <cstdlib>
 
using namespace std; //funciona cout cin
 
void Registrar();
void Ver();
void Modificar();
void Eliminar();
 
//struct sRegistro
//{
//	char codigo_iu[2];
//	char nombre_iu[60];
//}campo;
 
int main()
{
	bool bandera=false;
	char tecla;
	do
	{
		system("cls");
		cin.clear();
		cout <<"INDICES UNIFICADOS:" <<endl<<endl;
		cout <<"\t1. REGISTRAR" <<endl;
		cout <<"\t2. VER" <<endl;
		cout <<"\t3. MODIFICAR" <<endl;
		cout <<"\t4. ELIMINAR" <<endl;
		cout <<"\t5. SALIR";
		cout <<endl<<endl<< "Opcion: ";cin >>tecla;
 
		switch(tecla)
		{
			case '1':
				Registrar();
//				break;
			case '2':
				//Ver();//
				break;
			case '3':
				//Modificar();//
				break;
			case '4':
				//Eliminar();//
				break;
			case '5':
				bandera=true;
				break;
			default:
				cout <<endl<< "\tOpcion no valida.\a\n";
				break;
		}
	}while(bandera!=true);
	return 0;
}
 
void Registrar()
{
	char codigo_iu[2],nombre_iu[60];
//	string codigo_iu[2],nombre_iu[60];
	bool bandera2=false;
	FILE *alias;
	alias=fopen("D:\\bd_iu.dat","rb");
	if(alias==NULL)
	{
		cout<<"\n\rARCHIVO NO EXISTE, CREANDO BASE DE DATOS... ";
		alias=fopen("D:\\bd_iu.dat","wb");
		fclose(alias);
	}
	else
	{
		fclose(alias);
	}
//	alias=fopen("D:\\bd_iu.dat","ab+");
	system("cls");
	cout<<"DATOS A REGISTRAR:"<<endl;
	do
	{
		cout<<"\nI.U. (00 fin): ";cin >>codigo_iu;
		_flushall();
//		gets(codigo_iu);
		if(codigo_iu[0] == '0' && codigo_iu[1] == '0')
//		if(codigo_iu="00")
		{
//			fclose(alias);
			bandera2=false;
			break;
		}
//		if(campo.codigo_iu[0] == '0' && campo.codigo_iu[1] == '0')break;
		cout<<"NOMBRE: ";cin>>nombre_iu;
		_flushall();
//		gets(nombre_iu);
		alias=fopen("D:\\bd_iu.dat","ab+");
		fputs(codigo_iu,alias);
		fputs(",",alias);
		fputs(nombre_iu,alias);
		fputs(",",alias);
		fclose(alias);
	}while(bandera2!=true);
//	fclose(alias);
	return;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (234 intervenciones) el 18/10/2014 18:38:21
Expresar cantidades en milesimas puede inducir a equívocos.
Lo expresaremos en %

Redondeando números.
1/2 = 0.50.
1.5/2 = 0.25.

Lo cual quiere decir que el código que yo propongo se ejecuta entre un 25 y 50% más rápido, medido en mi máquina.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Manejo de ficheros en C

Publicado por Chema (1 intervención) el 19/10/2014 11:26:58
Ruben Blades canción 'Pedro Navaja'
.....Cuando lo manda el destino no lo cambia ni el más bravo,
si naciste pa' martillo del cielo te caen los clavos.
La vida te da sorpresas, sorpresas te da la vida ay Dios.

Tenía amistad con un excelente programador , pero había nacido "pa martillo", el tipo todo lo arreglaba metiendo en un árbol binario los datos de un fichero csv, no conocía otra cosa, toda su técnica consistía en meterlo todo a martillazos en un árbol binario.

Un día me presenta un proyecto profesional, consistía en atacar csv de gran tamaño y realizar operaciones matemáticas sobre cada campo y cada linea y realizar un acumulado tipo tabla por conceptos y presentarlo en html . El tipo con su arbol binario, su técnica y un fichero de 10.000.000 de lineas realizaba, (10.000.000 de lineas x 10 campos = 100.000.000 + 10.000.000 = 110.000.000 de malloc, y usaba 100 megas de memoria
.
Le demostré que el mismo resultado se obtenía usando 1 malloc, y 100 x 100 x sizeof(int) = 40.000 bytes. +- 40 K de memoria.

El tipo se enfadó conmigo.

Moraleja, si sabes mucho de algo, mejor escribe un libro y gana dinero que discutir con martillos y sus clavos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar