[Powered by Google Translate] [File I / O] [Jason Hirschhorn, Harvard University] [Esta é CS50, CS50.TV] Cando pensamos nun arquivo, o que vén á mente é un documento de Microsoft Word, unha imaxe JPEG ou unha música MP3, e interactuar con cada un destes tipos de arquivos de diferentes xeitos. Por exemplo, nun documento de Word, engadir texto mentres unha imaxe JPEG podemos cortar os bordos ou retocar as cores. Con todo, baixo a capa de todos os ficheiros no noso ordenador son nada máis dunha longa secuencia de ceros e uns. É ata a aplicación específica que interactúa co arquivo para decidir como procesar esa longa secuencia e presenta-lo para o usuario. Por unha banda, un documento pode ver só un byte, ou oito ceros e uns, e amosar un carácter ASCII na pantalla. Por outra banda, unha imaxe de mapa de bits pode ver 3 bytes, ou 24 ceros e uns, e interpretala los como tres números hexadecimais que representan os valores de vermello, verde e azul nun pixel dunha imaxe. O que poden ollar como na pantalla, no seu núcleo, arquivos non son nada máis que unha secuencia de ceros e uns. Entón imos mergullar para ver como realmente manipular eses ceros e uns cando se trata de escribir e ler un arquivo. Vou comezar por división lo en un proceso de 3-parte sinxelo. A continuación, vou mergullo en dous exemplos de código que demostran estas tres partes. Finalmente, eu vou revisar o proceso e algúns dos seus detalles máis importantes. Como ocorre con calquera arquivo que senta no seu escritorio, A primeira cousa a facer é abri-lo. C facemos iso declarando un punteiro para unha estrutura predefinida que representa un ficheiro no disco. Nesta chamada de función, tamén decidir se quere escribir ou ler a partir do ficheiro. A continuación, facemos a lectura real e da escritura. Hai un número de funcións especializadas, podemos utilizar nesta parte, e case todos eles comezan coa letra F, que está a arquivo. Pasado, semellante aos X vermellas pequenas na parte superior dos arquivos abrir no seu ordenador, imos pechar o ficheiro con unha chamada de función final. Agora que temos unha idea xeral do que imos facer, imos mergullar no código. Neste directorio, temos dous arquivos C e os seus arquivos executable correspondentes. O programa da máquina de escribir ten un argumento de liña de comandos, o nome do documento que desexa crear. Neste caso, imos chamalo Doc.txt. Imos executar o programa e introduce un par de liñas. Oi O meu nome é Jason. Por fin, imos escribir "Quit". Agora listar todos os ficheiros no directorio, vemos que existe un novo documento chamado Doc.txt. Ese é o arquivo de programa recén criado. E, por suposto, iso non é nada máis que unha longa secuencia de ceros e uns. Se abrirmos este novo arquivo, vemos as tres liñas de código que celebramos o noso programa - Oi Maio é o nome Jason. Pero o que está realmente a suceder cando typewriter.c funciona? A primeira liña de interese para nós é a liña 24. Nesta liña, declaramos a nosa punteiro do ficheiro. A función que retorna este punteiro, fopen, ten dous argumentos. O primeiro é o nome do ficheiro, incluíndo a extensión do ficheiro, se fose necesario. Lembre que unha extensión de arquivo non inflúe o ficheiro no seu nivel máis baixo. Estamos sempre lidando con unha longa secuencia de ceros e uns. Pero iso non influencia como os arquivos son interpretados e cales aplicacións son utilizados para abri-los. O segundo argumento para fopen é unha única letra que representa o que desexa facer despois de abrir o ficheiro. Hai tres opcións para ese argumento - W, R e A. Nós escoller w neste caso, porque queremos escribir para o arquivo. R, como podes imaxinar, é que a lectura do ficheiro. E un é para engadir ao ficheiro. Aínda que ambos W e pode ser usado para a gravación de ficheiros, w vai comezar a escribir a partir do inicio do ficheiro e potencialmente substituír todos os datos que foron previamente almacenados. Por defecto, o ficheiro que abrir, se non hai, é creado no noso directorio actual de operación. No entanto, se queremos acceder ou crear un arquivo en un lugar diferente, no primeiro argumento fopen, podemos especificar un camiño de ficheiro, ademais do nome do ficheiro. Aínda que a primeira parte deste proceso é só unha liña de código longo, é sempre unha boa práctica incluír outro conxunto de liñas que comprobe que o ficheiro foi aberto ou creado. Se fopen retorna nulo, que non quere seguir adiante co noso programa, e isto pode ocorrer se o sistema operativo é falta de memoria ou tentar abrir un arquivo de un cartafol para o que non tiña os permisos axeitadas. A segunda parte do proceso ocorre en malla máquina de escribir do tempo. Usamos unha función de biblioteca CS50 para a entrada do usuario, e asumindo que eles non queren saír do programa, usan os fputs función para sacar a corda e gravala-lo para o arquivo. fputs é só unha das moitas funcións que poderiamos usar para gravar o ficheiro. Outros inclúen fwrite, fputc, e mesmo fprintf. Independentemente da función particular que acaban empregando, non obstante, todos eles precisan de saber, por medio dos seus argumentos, polo menos dúas cousas - o que ten que ser escrito e onde debe ser escrito. No noso caso, a entrada é a cadea que debe ser escrito e FP é o punteiro que orienta-nos cara a onde estamos escribindo. Neste programa, a segunda parte do proceso é moi sinxelo. Estamos simplemente tomar unha cadea de usuario e engadir lo directamente para o noso arquivo con pouco ou ningún validación de entrada ou comprobacións de seguridade. Moitas veces, porén, a parte dous vai ocupar a maior parte do seu código. Finalmente, a terceira parte é na liña 58, onde se pecha o arquivo. Aquí chamamos fclose e pasalo a nosa punteiro do ficheiro orixinal. Na liña seguinte, volvemos cero, sinalizando o fin do noso programa. E, si, a terceira parte é tan sinxelo coma iso. Imos pasar á lectura de arquivos. Volver no noso directorio temos un arquivo chamado printer.c. Imos executa-lo co ficheiro que acabamos de crear - Doc.txt. Este programa, como o nome suxire, vai simplemente imprimir o contido do arquivo pasado para el. E aí temos iso. As liñas de código que ingresaran anteriormente e gardados en Doc.txt. Oi O meu nome é Jason. Se mergullo printer.c, vemos que unha gran parte do código é semellante ao que acabamos atravesou en typewriter.c. En realidade a liña 22, onde abrimos o arquivo, e liña 39, onde nós pechamos o ficheiro, son ambos case idéntico ao typewriter.c, para salvar argumento fopen segundo. Esta vez, estamos lendo un ficheiro, Entón, temos escollido r en vez de w. Así, imos nos centrarse na segunda parte do proceso. Na liña 35, como a segunda condición no noso lazo 4, facemos unha chamada a fgets, a función de acompañante para fputs de antes. Desta vez temos tres argumentos. O primeiro é o punteiro para a matriz de caracteres en que a cadea será almacenado. O segundo é o número máximo de caracteres a seren lidos. E o terceiro é o punteiro para o arquivo co cal estamos a traballar. Vostede vai entender que o loop remata cando fgets retorna nulo. Hai dúas razóns que iso pode acontecer. En primeiro lugar, un erro pode ocorrer. En segundo lugar, e máis probable, a fin do ficheiro alcanzado e os personaxes non máis foron lidos. No caso de que estea se pregunta, dúas funcións que non existen nos permiten dicir que a razón é a causa deste punteiro nulo particular. E non é de sorprender, xa que teñen que ver coa traballar con arquivos, tanto a función ferror eo inicio función feof coa letra f. Finalmente, antes de concluír, unha nota rápida sobre o fin da función de arquivo, que, como xa se mencionou, é escrito como feof. Moitas veces vai atopar-se con tempo e loops para progresivamente ler o seu camiño a través de arquivos. Así, vai ter unha forma de acabar con estes lazos despois de chegar ao final destes arquivos. Chamando feof no seu punteiro do ficheiro e comprobar a ver se é verdade faría exactamente isto. Así, un loop while coa condición (! Feof (FP)) pode parecer unha solución perfectamente adecuada. Con todo, dicir que temos unha liña de esquerda no noso arquivo de texto. Nós imos entrar no noso loop while e todo vai funcionar como planificado. Na seguinte rolda través, o noso programa vai comprobar a ver se feof de FP é verdade, pero - e este é o punto crucial para entender aquí - non será verdade aínda. Iso porque o obxectivo de feof non é verificar a próxima chamada a unha función de lectura vai bater ao final do arquivo, senón para comprobar se hai ou non a fin do ficheiro xa foi alcanzado. No caso deste exemplo, ler a última liña do noso arquivo vai perfectamente ben, pero o programa non sabe que se loita ao final do noso arquivo. Non é ata que fai unha lectura adicional que contraría o final do arquivo. Así, unha condición correcta sería o seguinte: fgets e os seus tres argumentos - de saída, tamaño de produción e FP - e todo isto non é igual a nulo. Esta é a visión que adoptamos en printer.c, e, neste caso, tras a saída do lazo, podería chamar feof ou ferror para informar ao usuario canto á fundamentación específica para saír deste ciclo. Escribir e ler un arquivo é, na súa forma máis básica, un proceso de 3-parte sinxelo. Primeiro, abra o arquivo. En segundo lugar, poñemos algunhas cousas no noso arquivo ou quitar algunhas cousas fóra. En terceiro lugar, peche o ficheiro. A primeira ea última son fáciles. A parte do medio é onde o material está complicado. E aínda que debaixo do capó que estamos sempre lidando con unha longa secuencia de ceros e uns, non axuda cando a codificación para engadir unha capa de abstracción que transforma a secuencia en algo que se parece máis ao que estamos afeitos a ver. Por exemplo, se estamos a traballar con un arquivo de bitmap de 24 bits, imos probablemente estar lendo ou escribindo tres bytes de cada vez. Neste caso, non tería sentido para definir e nomear correctamente unha estrutura que é de 3 bytes grande. A pesar de traballar con arquivos pode parecer complicado, usalos nos permite facer algo verdadeiramente notable. Podemos cambiar o estado do mundo fóra do noso programa, podemos crear algo que vive alén da vida do noso programa, ou podemos ata cambiar algo que foi creado antes do noso programa comezou a funcionar. Interactuar con arquivos é unha parte verdadeiramente poderosa de programación en C. e estou animado para ver o que vai crear con el no código de vir. O meu nome é Jason Hirschhorn. Este é CS50. [CS50.TV] [Risas] Okay. Un exame. Aquí imos nós. Cando pensamos nun arquivo - >> Oh, agarde. Sentímolo. [Risas] Certo. Hey there. Cando pensamos nun arquivo - Cando vostede pensa nun arquivo - Correcto. Dime cando estea listo. Ah, xenial. Aínda que a lectura dun teleprompter poida parecer - non. O meu mal.