You are on page 1of 13

7.ManejodeArchivosenC. Losdatosquehemostratadohastaelmomentohanresididoenlamemoriaprincipal.Sin embargo,las grandescantidadesdedatossealmacenannormalmenteenundispositivodememoriasecundaria. Estas coleccionesdedatosseconocencomoarchivos(antiguamenteficheros). Unarchivoesunconjuntodedatosestructuradosenunacoleccindeentidadeselementaleso bsicas denominadasregistrosquesondeigualtipoyconstanasuvezdediferentesentidadesdenivelms bajos denominadascampos. Haydostiposdearchivos,archivosdetextoyarchivosbinarios.Unarchivodetextoesuna secuenciade caracteresorganizadasenlneasterminadasporuncarcterdenuevalnea.

Enestosarchivosse pueden almacenarcanciones,fuentesdeprogramas,basededatossimples,etc.Losarchivosdetextose caracterizanpor serplanos,esdecir,todaslasletrastienenelmismoformatoynohaypalabrassubrayadas,ennegrita,o letrasde distintotamaooancho. Unarchivobinarioesunasecuenciadebytesquetienenunacorrespondenciaunoaunoconun dispositivo externo.Asquenotendrlugarningunatraduccindecaracteres.Adems,elnmerodebytesescritos (ledos) serelmismoquelosencontradoseneldispositivoexterno.Ejemplosdeestosarchivosson Fotografas,imgenes, textoconformatos,archivosejecutables(aplicaciones),etc. Enc,unarchivoesunconceptolgicoquepuedeaplicarseamuchascosasdesdearchivosde discohasta terminalesounaimpresora.Seasociaunasecuenciaconunarchivoespecificorealizandouna operacinde apertura.Unavezqueelarchivoestabierto,lainformacinpuedeserintercambiadaentreesteyel programa. Sepuedeconseguirlaentradaylasalidadedatosaunarchivoatravsdelusodelabibliotecade funciones;CnotienepalabrasclavesquerealicenlasoperacionesdeE/S.Lasiguientetabladaun breveresumen delasfuncionesquesepuedenutilizar.SedebeincluirlalibreraSTDIO.H.Observequela mayoradelas funcionescomienzanconlaletraF,estoesunvestigiodelestndarCdeUnix. NombreFuncin fopen()Abreunarchivo.

fclose()Cierraunarchivo. fgets()Leeunacadenadeunarchivo. fputs()Escribeunacadenaenunarchivo fseek()Buscaunbyteespecificodeunarchivo. fprintf()Escribeunasalidaconformatoenelarchivo. fscanf()Leeunaentradaconformatodesdeelarchivo. feof()Devuelveciertosisellegaalfinaldelarchivo. ferror()Devuelveciertosiseproduceunerror. rewind()Colocaellocalizadordeposicindelarchivoalprincipiodelmismo. remove()Borraunarchivo. fflush()Vacaunarchivo. Elpunteroaunarchivo. ElpunteroaunarchivoeselhilocomnqueunificaelsistemadeE/Sconbuffer.Unpunteroaun archivoes unpunteroaunainformacinquedefinevariascosassobrel,incluyendoelnombre,elestadoyla posicinactual delarchivo.Enesenciaidentificaunarchivoespecificoyutilizalasecuenciaasociadaparadirigirel funcionamiento delasfuncionesdeE/Sconbuffer.UnpunteroaunarchivoesunavariabledetipopunteroaltipoFILE quese defineenSTDIO.H.Unprogramanecesitautilizarpunterosaarchivosparaleeroescribirenlos mismos.Para obtenerunavariabledeestetiposeutilizaunasecuenciacomoesta: FILE*F; Aperturadeunarchivo. Lafuncinfopen()abreunasecuenciaparaquepuedaserutilizadaylaasociaaunarchivo.Su prototipoes: FILE*fopen(constcharnombre_archivo,costcharmodo); Dondenombre_archivoesunpunteroaunacadenadecaracteresquerepresentanunnombre validodel archivoypuedeincluirunaespecificacindeldirectorio.Lacadenaalaqueapuntamododetermina comoseabreel archivo.Lasiguientetablamuestralosvalorespermitidosparamodo. ModoSignificado rAbreunarchivodetextoparalectura. wCreaunarchivodetextoparaescritura. aAbreunarchivodetextoparaaadir. rbAbreunarchivobinarioparalectura. wbCreaunarchivobinarioparaescritura. abAbreunarchivobinarioparaaadir. r+Abreunarchivodetextoparalectura/escritura.

w+Creaunarchivodetextoparalectura/escritura. a+Aadeocreaunarchivodetextoparalectura/escritura. r+bAbreunarchivobinarioparalectura/escritura. w+bCreaunarchivobinarioparalectura/escritura. a+bAadeocreaunarchivobinarioparalectura/escritura. Lafuncinfopen()devuelveunpunteroaarchivo.Unprogramanuncadebealterarelvalordeese puntero. Siseproduceunerrorcuandoseestaintentandoabrirunarchivo,fopen()devuelveunpunteronulo. Sepuedeabrirunarchivobienenmodotextoobinario.Enlamayoradelasimplementaciones, enmodo texto,lasecuenciasderetornodecarro/saltodelneaseconviertenacaracteresdesaltodelneaen lectura.Enla escritura,ocurrelocontrario:loscaracteresdesaltodelneaseconviertenensaltodelnea.Estas conversionesno ocurrenenarchivosbinarios. LamacroNULLestdefinidaenSTDIO.H.Estemtododetectocualquiererroralabrirun archivo:comopor ejemplodiscollenooprotegidocontraescrituraantesdecomenzaraescribirenl. Siseusafopen()paraabrirunarchivoparaescritura,entoncescualquierarchivoexistenteconel mismo nombreseborrarysecreaunonuevo.Sinoexisteunarchivoconelmismonombre,entoncesse crear.Sise quiereaadiralfinaldelarchivoentoncesdebeusarelmodoa.Siseusaaynoexisteelarchivo,se devolverun error.Laaperturadeunarchivoparalasoperacionesdelecturarequierequeexistaelarchivo.Sino existe,fopen() devolverunerror.Finalmente,susseabreunarchivoparalasoperacionesdeleer/escribir,la computadoranolo borrarsiexiste;sinembargo,sinoexiste,lacomputadoralocrear. Cierredeunarchivo. Lafuncinfclose()cierraunasecuenciaquefueabiertamedianteunallamadaafopen().Escribe todala informacinquetodavaseencuentreenelbuffereneldiscoyrealizauncierreformaldelarchivoa niveldelsistema operativo.Unerrorenelcierredeunasecuenciapuedegenerartodotipodeproblemas,incluyendola prdidade datos,destruccindearchivosyposibleserroresintermitentesenelprograma.Elprototipodeesta funcines: intfclose(FILE*F); DondeFeselpunteroalarchivodevueltoporlallamadaafopen().Sisedevuelveunvalorcero significa

quelaoperacindecierrehatenidoxito.Generalmente,estafuncinsolofallacuandoundiscoseha retiradoantes detiempoocuandonoquedaespaciolibreenelmismo. Paraintroduciruobtenerdatosdeunarchivotenemoslassiguientescuatrofunciones: fprintf()yfscanf() Estasfuncionessecomportanexactamentecomoprinft()yscanf()discutidasanteriormente, exceptoque operansobrearchivo.Susprototiposson: intfprintf(FILE*F,constchar*cadena_de_control,.....); intfscanf(FILE*F,constchar*cadena_de_control,.....); DondeFesunpunteroalarchivodevueltoporunallamadaafopen().fprintf()yfscanf() dirigensus operacionesdeE/SalarchivoalqueapuntaF. Lasfuncionesfgets()yfputs()puedenleeryescribircadenasaodesdelosarchivos.Los prototiposde estasfuncionesson: char*fputs(char*str,FILE*F); char*fgets(char*str,intlong,FILE*F); Lafuncinputs()escribelacadenaaunarchivoespecifico.Lafuncinfgets()leeunacadena desdeel archivoespecificadohastaqueleeuncarcterdenuevalneaolongitud1caracteres. SiseproduceunEOF(EndofFile)lafuncingetsretornaunNULL. Funcionfeof() Cuandoseabreunarchivoparaentradabinaria,sepuedeleerunvalorenteroigualdelamarca EOF.Esto podrahacerquelarutinadelecturaindicaseunacondicindefindearchivoancuandoelfinfsico delmismonose hayaalcanzado.Pararesolveresteproblema,Cincluyelafuncinfeof(),quedeterminacuandoseha alcanzadoel findelarchivoleyendodatosbinarios.Lafuncintieneelsiguienteprototipo: intfeof(FILE*F); SuprototiposeencuentraenSTDIO.H.Devuelveciertosisehaalcanzadoelfinaldelarchivo,en cualquier otrocaso,0.Porsupuesto,sepuedeaplicarestemtodoaarchivosdetextotambin. Ahorabienparaelejemploanteriorustedincluirlosdatosdelaforma: Nombredelalumno1nota Nombredelalumno2nota ..... Algunasvecesustednecesitaramanipularporseparadoelnombredelalumnoysunota,paraesto es necesariosepararloencampos.Sepuederealizarintroduciendocaracteresdelimitadoresentrecampoy

campo,por ejemplo: fprinft(C,%s;%d\n,nombre,cal); Estogeneraraunarchivodetipo: Nombredelalumno1;nota Nombredelalumno2;nota ..... Lafuncinrewind()inicializaelindicadordeposicin,alprincipiodelarchivo,indicadoporsu argumento.Su prototipoes: voidrewind(FILE*F); DondeFesunpunteroaunarchivovlido.EstafuncinseencuentraenSTDIO.H Lafuncinferror()determinasisehaproducidoenerrorenunaoperacinsobreunarchivo.Su prototipo es: intferror(FILE*F); DondeFesunpunteroaunarchivovlido.Devuelveciertosisehaproducidounerrordurantela ultima operacinsobreelarchivo.Encasocontrario,devuelvefalso.Debidoaquecadaoperacinsobreel archivo actualizalacondicindeerror,sedebellamaraferror()inmediatamentedespusdelaoperacinde estetipo;sino seaseas,elerrorpuedeperderse.EstafuncinseencuentraenSTDIO.H Lafuncinremove()borraelarchivoespecificado.Suprototipoeselsiguiente: intremove(char*nombre_archivo); Devuelvecerositienexito.Sinounvalordistintodecero. Lafuncinfflush()escribetodoslosdatosalmacenadosenelbuffersobreelarchivoasociadocon un apuntador.Suprototipoes: intfflush(FILE*F); Sisellamaestafuncinconunpunteronulosevacianlosbuffersdetodoslosarchivosabiertos. Esta funcindevuelvecerositienexito,enotrocaso,devuelveEOF.

ArgumentosdeLneadeComando
Cproveeunmecanismoparapasarargumentosdesdelalneadecomandosalprogramaquesevaa ejecutar.Cuandoelprogramacomiezasuejecucin,larutinamainesllamadacondosargumentos:un contadoryunapuntadoraunarreglodecadenasdecaracteres.Elcontadoresllamdoporconvencin argcyelapuntadorargv.Elusodedeargvesunpocotruculento.Dadoqueargvesunapundadoraun

arreglodecadenasdecaracteres,laprimeracadenadecaracteresesreferenciadaporargv[0](o*argv). Lasegundacadenaisreferenciadaporargv[1](o*(argv+1)),laterceraporargv[2],yas sucesivamente.Laprimeracadenadecaracteres,argv[0],contieneelnombredelprograma.Los argumentoscomienzanrealmenteconargv[1]. Unejemplodellamadadeunprogramallamadocopia,quecopieunarchivoenotroarchivoseria: copiafuente.txtdestino.txt.Estoes,elnombredelprogramamasdosargumentosquecorresponderian alosnombresdelosarchivosfuenteydestino. Veamosunejemploquesimplementemuestralosargumentosdeunprograma.


#include<stdio.h> int main(int argc, char *argv[]) { int i; fprintf("The number of command line arguments is %d\n", argc); fprintf("The program name is %s\n",argv[0]); for (i = 1; i < argc; i++) { fprintf("%s",argv[i]); } fprintf("\n"); return 0;

fputs

Lafuncinfputsescribeunacadenaenunfichero.Noseaadeelcarcterderetornodelneaniel carcternulofinal.ElvalorderetornoesunnmerononegativooEOFencasodeerror.Los parmetrosdeentradasonlacadenaaescribiryunpunteroalaestructuraFILEdelficherodondese realizarlaescritura. Elprototipocorrespondientedefputses:


int fputs(const char *buffer, FILE *archivo)

paraversufuncionamientomostramoselsiguienteejemplo:
#include <stdio.h> int main ( int argc, char **argv ) { FILE *fp;

char cadena[] = "Mostrando el uso de fputs en un fichero.\n"; fp = fopen ( "fichero.txt", "r+" ); fputs( cadena, fp ); fclose ( fp ); } return 0;

fputs
Lafuncinfputsescribeunacadenaenunfichero.Noseaadeelcarcterderetornodelneaniel carcternulofinal.ElvalorderetornoesunnmerononegativooEOFencasodeerror.Los parmetrosdeentradasonlacadenaaescribiryunpunteroalaestructuraFILEdelficherodondese realizarlaescritura. Elprototipocorrespondientedefputses:
int fputs(const char *buffer, FILE *archivo)

paraversufuncionamientomostramoselsiguienteejemplo:
#include <stdio.h> int main ( int argc, char **argv ) { FILE *fp; char cadena[] = "Mostrando el uso de fputs en un fichero.\n"; fp = fopen ( "fichero.txt", "r+" ); fputs( cadena, fp ); fclose ( fp ); } return 0;

fgets
Estafuncinestdiseadaparaleercadenasdecaracteres.Leerhastan1caracteresohastaqueleaun retornodelnea.Enesteltimocaso,elcarcterderetornodelneatambinesledo. Elprototipocorrespondientedefgetses:

char *fgets(char *buffer, int tamao, FILE *archivo);

Elprimerparmetrobufferlohemosllamadoasporqueesunpunteroaunespaciodememoriadel tipochar(podramosusarunarreglodechar).Elsegundoparmetroestamaoqueesellimiteen cantidaddecaracteresaleerparalafuncionfgets.Yporultimoelpunterodelarchivoporsupuestoque eslaformaenquefgetssabraaquearchivodebeleer.


#include <stdio.h> #include <stdlib.h> int main() { FILE *archivo; char caracteres[100]; archivo = fopen("prueba.txt","r"); if (archivo == NULL) exit(1); printf("\nEl contenido del archivo de prueba es \n\n"); while (feof(archivo) == 0) { fgets(caracteres,100,archivo); printf("%s",caracteres); } } return 0;

Esteeselmismoejemplodeantesconladiferenciadequeestehaceusodefgetsenlugardefgetc.La funcinfgetssecomportadelasiguientemanera,leerdelarchivoapuntadoporarchivoloscaracteres queencuentreyaponerlosenbufferhastaqueleauncaractermenosquelacantidaddecaracteres especificadaentamaoohastaqueencuentreelfinaldeunalinea(\n)ohastaqueencuentreelfinaldel archivo(EOF).Enesteejemplonovamosaprofundizarmasqueparadecirquecaracteresesunbuffer, lospormenoresseranexplicadosenlaseccindemanejodinmicodememoria. Elbeneficiodeestafuncinesquesepuedeobtenerunalineacompletaalavez.Yresultamuytil paraalgunosfinescomolaconstruccindeunparserdealgntipodearchivodetexto.

fprintf
Lafuncinfprintffuncionaigualqueprintfencuantoaparmetros,perolasalidasedirigeaun ficheroenlugardealapantalla. Elprototipocorrespondientedefprintfes:
int fprintf(FILE *archivo, const char *formato, argumento, ...);

Podemosverunejemplodesuuso,abrimoseldocumento"fichero.txt"enmodolectura/escrituray escribimosdentrodeel.
#include <stdio.h> int main ( int argc, char **argv ) { FILE *fp; char buffer[100] = "Esto es un texto dentro del fichero."; fp = fopen ( "fichero.txt", "r+" ); fprintf(fp, buffer); fprintf(fp, "%s", "\nEsto es otro texto dentro del fichero."); fclose ( fp ); } return 0;

fscanf
Lafuncinfscanffuncionaigualquescanfencuantoaparmetros,perolaentradasetomadeun ficheroenlugardelteclado. Elprototipocorrespondientedefscanfes:
int fscanf(FILE *fichero, const char *formato, argumento, ...);

Podemosverunejemplodesuuso,abrimoseldocumento"fichero.txt"enmodolecturayleyendo dentrodeel.
#include <stdio.h> int main ( int argc, char **argv ) { FILE *fp; char buffer[100]; fp = fopen ( "fichero.txt", "r" ); fscanf(fp, "%s" ,buffer); printf("%s",buffer); fclose ( fp ); return 0; }

fread

size_tfread(void*ptr,size_tsize,size_tcount,FILE*stream); Estafuncinleeunbloquedeuna"stream"dedatos.Efectalalecturadeunarreglodeelementos "count",cadaunodeloscualestieneuntamaodefinidopor"size".Luegolosguardaenelbloquede memoriaespecificadopor"ptr".Elindicadordeposicindelacadenadecaracteresavanzahastaleerla totalidaddebytes.Siestoesexitosolacantidaddebytesledoses(size*count). PARAMETROS: ptr:Punteroaunbloquedememoriaconuntamaomnimode(size*count)bytes. size:Tamaoenbytesdecadaelemento(delosquevoyaleer). count:Nmerodeelementos,loscualestienenuntamao"size". stream:PunteroaobjetosFILE,queespecificalacadenadeentrada.

fwrite
Estafuncinestpensadaparatrabajarconregistrosdelongitudconstanteyformaparejaconfread.Es capazdeescribirhaciaunficherounoovariosregistrosdelamismalongitudalmacenadosapartirde unadireccindememoriadeterminada.Elvalorderetornoeselnmeroderegistrosescritos,noel nmerodebytes.Losparmetrosson:unpunteroalazonadememoriadedondeseobtendrnlos datosaescribir,eltamaodecadaregistro,elnmeroderegistrosaescribiryunpunteroala estructuraFILEdelficheroalqueseharlaescritura. Elprototipocorrespondientedefwritees:
size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);

Unejemploconcretodelusodefwriteconsucontrapartefreadyusandofuncioneses:
/*

* * * * */

FicheroCompleto.c Copyright 2009 Julio Csar Brizuela <brizuela@linux-qxlk>

#include <stdio.h> void void void void menu(); CrearFichero(FILE *Fichero); InsertarDatos(FILE *Fichero); VerDatos(FILE *Fichero);

struct sRegistro { char Nombre[25]; int Edad; float Sueldo; } registro; int main(int argc, char** argv) { int opcion; int exit = 0; FILE *fichero; while (!exit) { menu(); printf("\nOpcion: "); scanf("%d", &opcion); switch(opcion) { case 1: break; case 2: break; case 3: break; case 4: exit = 1; break; default: printf("\nopcion no valida"); } } void menu() { printf("\nMenu:"); printf("\n\t1. Crear fichero"); printf("\n\t2. Insertar datos"); } InsertarDatos(fichero); VerDatos(fichero);

CrearFichero(fichero);

return 0;

printf("\n\t3. Ver datos"); printf("\n\t4. Salir");

void CrearFichero(FILE *Fichero) { Fichero = fopen("fichero", "r"); if(!Fichero) { Fichero = fopen("fichero", "w"); printf("\nArchivo creado!"); } else { printf("\nEl fichero ya existe!"); } fclose (Fichero); return; } void InsertarDatos(FILE *Fichero) { Fichero = fopen("fichero", "a+"); if(Fichero == NULL) { printf("\nFichero no existe! \nPor favor creelo"); return; } printf("\nDigita el nombre: "); scanf("%s", registro.Nombre); printf("\nDigita la edad: "); scanf("%d", &registro.Edad); printf("\nDigita el sueldo: "); scanf("%f", &registro.Sueldo); fwrite(&registro, sizeof(struct sRegistro), 1, Fichero); fclose(Fichero); return; } void VerDatos(FILE *Fichero) { int numero = 1; Fichero = fopen("fichero", "r"); if(Fichero == NULL) { printf("\nFichero no existe! \nPor favor creelo");

return; } fread(&registro, sizeof(struct sRegistro), 1, Fichero); printf("\nNumero \tNombre \tEdad \tSueldo"); while(!feof(Fichero)) { printf("\n%d \t%s \t%d \t%.2f", numero, registro.Nombre, registro.Edad, registro.Sueldo); fread(&registro, sizeof(struct sRegistro), 1, Fichero); numero++; } fclose(Fichero); } return;

[editar]

You might also like