COLUMNA: Ata o momento, é probable que a maioría dos seus programas ser un pouco efémera. Executar un programa como Mario ou ávido. Fai algo, quizais solicitará o usuario para unha información, imprimir algunha saída para a pantalla, pero, a continuación, cando o programa acabou, non hai realmente ningunha evidencia alí nunca foi executado en primeiro lugar. Quero dicir, por suposto, que pode deixar el abrir a fiestra da terminal, pero se limpar a súa pantalla, non hai realmente ningunha evidencia de que existía. Non temos un medio de almacenamento información persistente, información que hai despois do noso programa deixou de funcionar, ou que non ten, ata este punto. Afortunadamente, porén, fai c proporcionar-nos coa capacidade facelo a través da posta en marcha algo chamado un arquivo, unha estrutura que basicamente representa un ficheiro que dobraría prema no seu ordenador, se está usado para un ambiente de usuario gráfica. Dun modo xeral cando se traballa con c, estamos, en realidade, vai estar traballando con punteiros para files-- ficheiro stars-- con excepción de un pouco cando falamos dunha parella de que as funcións traballar con punteiros de arquivo. Non é preciso ter realmente cavou moi profundo entendemento punteiros si. Hai un pouco de hippies onde iremos falar sobre eles, pero xeralmente o ficheiro e punteiros punteiros, mentres interrelacionados, non son exactamente o mesmo. Agora o que quero dicir cando Digo datos persistentes? ¿Qué son datos persistentes? Por que nos preocupa con iso? Digamos que, por exemplo, que está executando un programa ou que teña reescrito un programa que é un xogo, e quere manter o control de todos os movementos do usuario de xeito que se cadra, se algo sae mal, pode revisar o ficheiro despois do partido. Iso é o que queremos dicir cando falar datos persistentes. No decurso da execución do seu programa, un arquivo é creado. E cando o seu programa deixou de funcionar, o ficheiro aínda existe no seu sistema. E podemos ollar para el e examina-lo. E así que o programa sería definida como crearon algúns datos persistentes, existen datos despois do programa rematar a execución. Agora todas estas funcións que funcionan coa creación de ficheiros e manipulación los de diversos xeitos vivir io.h estándar, que é un ficheiro de cabeceira que probablemente foi libra incluíndo na parte superior da considerablemente moi todos os seus programas porque contén un dos a maioría das funcións útiles para nós, printf, que tamén permite vive io.h. estándar Entón non bater inclúen os ficheiros adicionais probablemente a fin de traballar con punteiros de arquivo. Agora, cada función de punteiro de arquivo único, ou cada ficheiro I / O, de entrada e saída función, acepta como un dos seus parámetros ou insumos pointer-- un ficheiro gardado por exemplo, fopen, que é o que usa para obter o ficheiro punteiro en primeiro lugar. Pero despois de que abriu a arquivo e comeza punteiros de ficheiro, pode, a continuación, paso-los como argumentos para as varias funcións imos falar Hoxe en día, así como moitos outros de modo que pode traballar con arquivos. Polo tanto, hai seis fermosa os básicos comúns que imos falar hoxe. fopen eo seu compañeiro función fclose, fgetc ea súa función fputc compañeiro, e fread ea súa función compañeiro, fwrite. Entón imos directo ao asunto. fopen-- o que fai? Ben, el abre un arquivo eo dálle un punteiro de ficheiro a el, de modo que pode usar este arquivo punteiro como un argumento para calquera das outras funcións de E / S de ficheiro. O máis importante para lembrar con fopen é que, despois de ter aberto o ficheiro ou fixo unha conexión como a que aquí, ten que comprobar para asegurarse de que o punteiro que ten de volta non é igual a cero. Se aínda non asistiu o vídeo en punteiros, isto pode non ter sentido. Pero se tentar e dereference un recall punteiro nulo, seu programa probablemente sufrirán unha segmentación [inaudível]. Queremos estar seguro de que nós ten un punteiro de volta lexítimo. A gran maioría do tempo imos obter un punteiro lexítimo ao e non será un problema. Entón, como imos facer unha chamada para fopen? Parece moi bonito como este. Estrela ficheiro ptr-- PTR sendo un xenérico nome para o ficheiro pointer-- fopen e nós pasamos en dúas cousas, o nome do ficheiro e unha operación que queremos emprender. Así, poderiamos ter unha chamada que se parece isto-- estrela ficheiro PTR 1 é igual a fopen file1.txt. E a operación que escollín é r. Entón, o que pensas r é aquí? Cales son os tipos de cousas que Pode ser capaz de facer a ficheiros? Así, R é a operación que escoller cando queremos ler un arquivo. Por iso, sería, basicamente, cando facemos unha chamada como este estar recibindo nós un punteiro de ficheiro de tal forma que nós podería entón ler información de file1.txt. Do mesmo xeito, poderiamos abrir o ficheiro 2.txt para escribir e para que poidamos pasar ptr2, o punteiro do ficheiro que eu creei aquí, como un argumento para calquera función que grava información nun arquivo. E semellante á escrita, hai tamén a posibilidade de engadir, a. A diferenza entre escribindo e anexando sendo que cando gravar nun ficheiro, se fai unha chamada para fopen para a escrita e este ficheiro xa existe, é vai substituír o ficheiro. Comezará en principio, borrar toda a información que xa está aí. Tendo en conta que, se abri-lo para engadir, vai para o final do arquivo se xa existe texto ou información nel contidas, e vai entón comezar escrita de alí. Entón non vai perder calquera dos información que fixo antes. Se queres escribir ou achegar tipo de depende da situación. Pero probablemente vai saber o que o operación correcta é cando chega a hora. Entón, iso é fopen. E sobre fclose? Ben, moi simplemente, fclose só acepta o punteiro do ficheiro. E como podería esperar, el pecha o arquivo. E unha vez que pechou un ficheiro, non podemos realizar calquera arquivo de funcións de E / S, lendo ou escribindo, naquel arquivo. Temos que volver a abrir a presentar outra vez, a fin seguir traballando con Lo usando as funcións de I / O. Entón medios fclose estamos a facer traballar con este ficheiro. E todos necesitamos é pasar en o nome dun ficheiro de punteiro. Entón, nun par desliza atrás, fopened arquivo de texto 1 punto para a lectura e nós asignado que arquivo punteiro para ptr1. Agora decidimos que somos lectura feita a partir dese ficheiro. Non teñen que facer máis nada con el. Podemos ptr1 só fclose. E do mesmo xeito, poderiamos usar fclose os outros. Todo ben. De xeito que está abrindo e pechando. Estes son os dous básico operacións de partida. Agora queremos realmente facer algunhas cousas interesantes, ea primeira función que imos ver que vai facer iso é fgetc-- arquivar obter un personaxe. Iso é o que xeralmente fgetc se traduciría en. O seu obxectivo na vida é le o seguinte carácter, ou se esta é a súa moi primeira chamada para fgetc para un determinado arquivo, o primeiro carácter. Pero, entón, despois diso, comeza a próxima, o moi próximo carácter deste arquivo, e as almacena nunha variable de carácter. Como fixemos aquí, carácter ch igual fgetc, pasar o nome dun ficheiro de punteiro. De novo, é moi importante aquí para recordar que, a fin de ter esta operación foi un éxito, o propio punteiro do ficheiro debo ter foi aberto para lectura. Non podemos ler un personaxe dun ficheiro punteiro que abrimos para a escrita. Entón esta é unha das limitacións de fopen, non? Temos para restrinxir nós só para realizar unha operación cun punteiro de arquivo. Se quixésemos ler e escribir desde o mesmo arquivo, teriamos aberto dous separados punteiros de arquivos para o mesmo file-- unha lectura, unha para a escrita. Entón, de novo, a única razón Eu traio que ata agora é porque se nós estamos indo a facer unha chamada para fgetc, que debe ter un punteiro de ficheiro foi aberto para lectura. E, a continuación, moi simplemente, todo o que necesitamos facer é pasar o nome do punteiro do ficheiro. Entón ch carbón equivale a ptr1 fgetc. Isto vai levarnos a próxima character-- ou aínda, se este é o primeiro xa que xa se fixo esta chamada, o primeiro character-- de calquera ficheiro é apuntada por ptr1. Lembre que isto era un arquivo de texto de punto. Vai ter o primeiro carácter desa e imos almacena-lo no ch variable. Moi sinxelo. Entón, temos só mirou para tres funcións e xa nós pode facer algo moi ordenado. Entón, se tomamos esa capacidade de obtención dun personaxe e nós lazo ele-- tanto, continuar a recibir personaxes a partir dun ficheiro de cada vez máis e agora nós over-- pode ler cada personaxe dun ficheiro. E se nós imprimir cada personaxe inmediatamente despois de ler, temos agora lidos dun arquivo e seu contido impreso para a pantalla. Temos efectivamente concatenado o ficheiro en pantalla. E iso é o que o Comando cat Linux fai. Se escribe gato no nome do arquivo, imprimirá todos os contidos Arquivo da xanela do seu terminal. E así este pequeno lazo aquí, só tres liñas de código, pero duplica efectivamente o gato de comandos de Linux. Polo tanto, esta sintaxe pode Parece un pouco raro, pero aquí está o que está a suceder aquí. Mentres ch igual fgetc, PTR non é igual a EOF-- é un pouco todo, pero imos división la só polo que está claro sobre a sintaxe. Eu consolidouse lo por unha cuestión de espazo, aínda que é un pouco sintaticamente complicado. Polo tanto, esta parte no dereito verde agora, o que está facendo? Ben, iso é só o noso chamamento fgetc, non? Vimos que antes. É obtención dun personaxe dende o arquivo. A continuación, comparar ese carácter contra EOF. EOF é un valor especial que é definido io.h estándar, que é o fin do personaxe de arquivo. Entón, basicamente o que vai pasar é este ciclo vai ler un personaxe, comparar a EOF, o fin do personaxe de arquivo. No caso de que non se corresponden, polo que non ten chegou ao fin do ficheiro, imos imprimir ese personaxe para fóra. Entón imos voltar para o inicio do ciclo de novo. Nós imos chegar a un personaxe, comprobe contra EOF, imprimir lo, e así por diante e así por diante e así por diante, loop través desa forma ata que chegamos ao final do arquivo. E, a continuación, por ese punto, imos ter impreso fóra todo o contido do ficheiro. Entón, de novo, só vin fopen, fclose, e fgetc e xa podemos duplicar unha orde de terminal de Linux. Como dixen ao principio, tivemos fgetc e fputc, e fputc foi o compañeiro función de fgetc. E así, como pode imaxinar, é o equivalente escrito. Ela nos permite escribir único carácter nun arquivo. Unha vez máis, sendo a excepción, só como se fose con fgetc, o ficheiro que estamos escribindo para debe ser aberto para gravar ou para engadir. Se intentamos e utilizar fputc nun ficheiro que temos aberto para lectura, imos sufrir un pouco de un erro. A súa chamada é ben sinxelo. A capital de fputc ptr2, todo que vai facer é que é vai escribir a letra en A en arquivo de 2 punto o texto, que foi o nome do ficheiro que aberto e asignado o punteiro para ptr2. Entón, nós estamos indo a escribir un maiúsculo para ficheiro 2 texto punto. E nós imos escribir exclamación apuntar para o arquivo 3 dot texto, que foi apuntado por ptr3. Entón, de novo, moi sinxelo aquí. Pero agora podemos facer outra cousa. Temos este exemplo estabamos só pasando por riba sobre a posibilidade de replicar o gato De comandos de Linux, o que imprime para a pantalla. Ben, agora que temos a capacidade para ler caracteres de arquivos e escribir caracteres para arquivos, por que non podemos simplemente substituír ese chamar a printf cunha chamada a fputc. E agora temos duplicado cp, un comando moi básico Linux que falamos camiño longo atrás en Linux comandos vídeo. Temos efectivamente duplicados que aquí. Estamos lendo un personaxe e entón nós estamos escribindo este personaxe a outro arquivo. Lectura dun ficheiro, escrita a outro, máis e máis e outra vez ata chegar EOF. Temos ata o final do arquivar estamos intentando copiar. E por que imos escribir todo dos personaxes que necesitamos para o ficheiro que estamos escribindo. Polo tanto, este é cp, o comando de copia de Linux. A principios de Neste vídeo, eu tiña a excepción que queremos falar dun pouco sobre punteiros. Aquí está especialmente onde estamos vai falar punteiros ademais de presentar punteiros. Polo tanto, esta función parece medio asustado. Ten varios parámetros. Hai moita cousa a ocorrer aquí. Hai unha morea de diferentes cores e textos. Pero, realmente, non é máis que o versión xenérica do fgetc que nos permite obter calquera cantidade de información. Pode ser un pouco ineficiente se estamos caracteres quedando unha de cada vez, iteración a través do arquivo un carácter á vez. Non sería máis agradable para estar 100 á vez 500 ou ao mesmo tempo? Ben, fread ea súa función compañeiro fwrite, que nós imos falar sobre nun segundo, permitir-nos para facer exactamente isto. Podemos ler unha cantidade arbitraria de información dun ficheiro e almacena-lo nalgún lugar temporalmente. No canto de poder só axusta-lo nunha única variable, que pode ser necesario para almacena-lo nunha matriz. E así, pasamos en catro argumentos para fread-- un punteiro ata o lugar onde estamos indo para almacenar información, o grande cada unidade de información será, cantas unidades de información queremos adquirir, e de o ficheiro queremos obtelos. Probablemente mellor ilustrado cun exemplo aquí. Entón, imos dicir que declaramos un conxunto de 10 números enteiros. Acabamos declarado no apilar arbitrariamente int arr 10. Entón, iso é moi sinxelo. Agora, o que estamos facendo, con todo, é o frecall é que estamos tamaño do int lendo veces 10 bytes de información. Tamaño do int estar four-- que é o tamaño dun número enteiro no c. Entón, o que estamos facendo é que estamos lendo 40 bytes por valor de información a partir do ficheiro sinalado por PTR. E nós estamos almacenando os 40 bytes en algún lugar onde nós reservamos 40 bytes por valor de memoria. Afortunadamente, xa fixemos isto por declarando arr, esa matriz da dereita. Que é capaz de manter 10 unidades de catro bytes. Así, en total, pode almacenar 40 bytes pena de información. E agora estamos lendo 40 bytes de información do arquivo, e estamos almacenando o en arr. Teña en conta que do vídeo no que os punteiros o nome dunha matriz, como arr, é realmente só un punteiro para o seu primeiro elemento. Entón, cando pasamos en arr alí, nós son, en realidade, pasando un enlace. Do mesmo xeito que podemos facer isto-- Non necesariamente necesitamos gardar nosa tapón na pila. Tamén poderiamos reservar dinamicamente Un buffer como este, utilizando malloc. Lembre, cando reservar dinamicamente a memoria, estamos salvando o no heap, non a pila. Senón que é un buffer. Aínda, neste caso, é sostendo 640 bytes de información porque unha parella ocupa oito bytes. E nós estamos pedindo 80 deles. Queremos ter espazo para prender 80 habitacións dobres. Entón 80 veces 8 é de 640 bytes de información. E iso é chamada a fread recolección de 640 bytes de información a partir do ficheiro sinalado por PTR e almacena-lo agora en arr2. Agora tamén podemos tratar fread así como unha chamada a fgetc. Neste caso, nós estamos só tentando obter un personaxe a partir do ficheiro. E nós non necesitamos un array para conter un personaxe. Podemos simplemente almacena-lo unha variable de carácter. O problema, porén, é que cando só temos unha variable, necesitamos pasar na dirección desa variable pois recorda que o primeiro argumento para fread é un punteiro para a localización e memoria onde queremos gardar a información. Unha vez máis, o nome dun array é un punteiro. Entón, nós non temos que facer matriz e comercial. Pero c, o personaxe c aquí, non é unha matriz. É só unha variable. E por iso necesitamos pasar un c comercial para indicar que ese é o enderezo de onde queremos para almacenar este un byte de información, este personaxe que estamos recadando de PTR. Fwrite-- vou pasar por este un pouco máis quickly-- é practicamente o equivalente exacto de fread agás que é para a escrita en vez de ler, só como o outro-- tivemos aberto e próximo, obter un personaxe, escribir un personaxe. Agora é obter arbitraria cantidade de información, cantidade arbitraria dereito de información. Así como antes, podemos ter un array de 10 enteiros onde xa temos información almacenada, quizais. Foi, probablemente, algunhas liñas de código que debe ir entre estes dous onde cubrir con arr algo significativo. Eu enche-lo con 10 enteiros diferentes. E no seu lugar, o que eu son facendo está escribindo desde arr e traídos a información do arr. E eu estou tomando esta información e poñer-lo para o arquivo. Entón, en vez de ser desde o ficheiro para o buffer, agora imos de o buffer no ficheiro. Entón, é todo o contrario. Entón, de novo, como antes, podemos tamén teñen unha peza chea de memoria que temos dinamicamente alocados e lidos desde ese e escribir que para o ficheiro. E tamén temos unha única variable capaz de manter un byte de información, como un personaxe. Pero, de novo, cómpre pasar a dirección desa variable cando queremos ler a partir del. Así, podemos escribir a información atopamos nese enderezo para o punteiro do ficheiro, PTR. Hai moitas outras gran arquivo E / funcións que facer moitas cousas ademais de os que xa falamos sobre hoxe. Un par de os pode considerar útil son fgets e fputs, que son o equivalente de fgetc e fputc pero para a lectura unha única cadea de caracteres dun ficheiro. No canto dun único personaxe, ha ler unha cadea enteira. fprintf, que basicamente permite usa printf para escribir no ficheiro. Entón, así como pode facer o a substitución de variables usando a espazos reservados por cento i e por cento d, e así por diante, con printf pode tomar de forma semellante a secuencia de printf e imprimir algo como que a un arquivo. fseek-- se ten un reprodutor de DVD é a analoxía que eu costume usar aqui-- é unha especie de como usar o seu rebobinar e avanzar rapidamente botóns para mover a película. Do mesmo xeito, pode mover o ficheiro. Unha das cousas dentro que a estrutura de arquivo c que crea para vostede é un indicador de onde está no arquivo. Está no moi comezando, no byte cero? Está vostede en byte 100, 1000 bytes, etc.? Pode usar fseek para mover arbitrariamente ese indicador para adiante ou cara atrás. E ftell, de novo semellante a un lector de DVD, é como un pequeno reloxo que di cantos minutos e segundos están nunha película particular. Do mesmo xeito, ftell dille como moitos bytes está no arquivo. feof é unha versión diferente de detectar se ten chegou ao fin do ficheiro. E é unha función ferror que pode usar para detectar se algo ten ir traballo mal con un arquivo. De novo, iso é só rabuñando a superficie. Aínda hai moito máis arquivo E / funcións do estándar io.h. Pero iso probablemente vai te comezou a traballar con punteiros de arquivo. Eu son Doug Lloyd. Este é CS50.