[ Voltar ] [ Índice ] [ Avançar ]

11. Arquivos

11.1 Introdução

O sistema de E/S de C utiliza o conceito de streams e arquivos. Uma stream é um dispositivo lógico que representa um arquivo ou dispositivo. A stream é independente do arquivo ou dispositivo. Devido a isso, a função que manipula uma stream pode escrever tanto em um arquivo no disco quanto em algum outro dispositivo, como o monitor.

Existem dois tipos de streams: de texto e binária.

Em uma stream de texto podem ocorrer certas traduções de acordo com o sistema hospedeiro. Por exemplo, um caracter de nova linha pode ser convertido para os caracteres retorno de carro e alimentação de linha. Devido a isso pode não haver uma correspondência entre os caracteres da stream e do dispositivo externo; a quantidade de caracteres pode não ser a mesma.

A stream binária é uma sequência de bytes com uma correspondência de um para um com os bytes encontrados no dispositivo externo, isto é, não ocorre nenhuma tradução de caracteres. O número de bytes é o mesmo do dispositivo.

Um arquivo é interpretado pela linguagem C como qualquer dispositivo, desde um arquivo em disco até um terminal ou uma impressora. Para utilizar um arquivo você deve associá-lo a uma stream e, então, manipular a stream. Você associa um arquivo a uma stream através de uma operação de abertura.

Nem todos os arquivos tem os mesmos recursos. Por exemplo, um arquivo em disco pode suportar acesso aleatório enquanto um teclado não.

Do que foi até aqui exposto concluímos que todas as streams são iguais, mas não todos os arquivos.

Se o arquivo suporta acesso aleatório, abrí-lo inicializa o indicador de posição apontando para o começo do arquivo. Quando cada caracter é lido ou escrito no arquivo, o indicador de posição é incrementado.

Um arquivo é desassociado de uma stream através de uma operação de fechamento. Se um arquivo aberto para saída por fechado, o conteúdo de sua stream será escrito no dispositivo externo. Esse processo é geralmente chamado de descarga (flushing) da stream e garante que nenhuma informação seja acidentalmente deixada no buffer de disco.

A stream associa o arquivo a uma estrutura do tipo FILE. Esta estrutura é definida no arquivo de cabeçalho stdio.h

11.2 Funções utilizadas para manipulação de arquivos

As principais funções para manipulação de arquivos são:

FUNÇÃO FINALIDADE
fopen( ) Abrir um arquivo
fclose( ) Fechar um arquivo
putc( ) Escrever um caracter em um arquivo
fputc( ) Idem putc( )
getc( ) Ler um caracter de um arquivo
fgetc( ) Idem getc( )
fseek( ) Posicionar o ponteiro de arquivo num byte específico
fprintf( ) É para o arquivo o que printf é para o console
fscanf( ) É para o arquivo o que scanf é para o console
feof( ) Devolve verdadeiro se o fim do arquivo foi atingido
ferror( ) Devolve verdadeiro se ocorreu um erro
rewind( ) Posicionar o ponteiro de arquivo no início deste
remove( ) Apagar um arquivo
fflush( ) Descarregar um arquivo

Todas estas funções estão no arquivo de cabeçalho stdio.h.

Este arquivo de cabeçalho define três tipos: size_t, fpos_t e FILE. Os dois primeiros são o mesmo que unsigned e o terceiro é discutido mais abaixo.

Este arquivo de cabeçalho também define várias macros. As importantes para a manipulação de arquivos são: NULL, EOF, FOPEN_MAX, SEEK_SET, SEEK_CUR e SEEK_END.

NULL define um ponteiro nulo.

EOF geralmente é definida como -1 e devolve este valor quando uma função de entrada tenta ler além do final do arquivo.

FOPEN_MAX define um valor inteiro que determina o número de arquivos que podem ser abertos ao mesmo tempo.

SEEK_SET, SEEK_CUR e SEEK_END são usadas com a função fssek( ) para o acesso aleatório a um arquivo.

11.3 O ponteiro de arquivo

Basicamente um ponteiro de arquivo identifica um arquivo específico e é usado pela stream para direcionar as operações das funções de E/S. Um ponteiro de arquivo é uma variável ponteiro do tipo FILE. Esta variável é um tipo pré-definido pela linguagem C. Normalmente ela é definida no arquivo de cabeçalho stdio.h, mas isso depende do seu compilador. Para ler ou escrever em arquivos seu programa precisa usar os poteiros de arquivo. Para declarar uma variável como ponteiro de arquivo use a seguinte sintaxe:

FILE *arquivo;

11.4 Abrindo um arquivo

Apesar do sistema de E/S de C considerar arquivo como qualquer dispositivo, para os conceitos apresentados daqui pra frente, consideraremos arquivo como um arquivo em disco.

Para abrir uma stream e associá-la a um arquivo você usa a função fopen( ) ,cuja sintaxe é:

fopen(ARQUIVO,MODO)

Onde ARQUIVO é um ponteiro para uma string que representa o nome do arquivo. Na prática é o nome do arquivo propriamente dito e pode ser um PATH, ou seja, algo como "C:\docs\arquivo.txt", no windows; ou algo como "/home/samu/arquivo.txt" no linux. MODO é uma string que representa como o arquivo será aberto de acordo com a tabela abaixo:

MODO COMO O ARQUIVO SERÁ ABERTO
r Abre um arquivo texto para leitura.
w Abre um arquivo texto para escrita. Se um arquivo com o mesmo nome existir, será sobrescrito.
a Abre um arquivo texto para anexação. Se o arquivo não existir, será criado.
rb Abre um arquivo binário para leitura.
wb Abre um arquivo binário para escrita. Se um arquivo com o mesmo nome existir, será sobrescrito.
ab Abre um arquivo binário para anexação. Se o arquivo não existir, será criado.
r+
w+
a+
Abre um arquivo texto para leitura/escrita. Se o arquivo não existir, será criado.
r+b
w+b
a+b
rb+
wb+
ab+
Abre um arquivo binário para leitura/escrita. Se o arquivo não existir, será criado.

É importante lembrar que em muitas implementações, no modo texto, a sequência de caracteres retorno de carro/alimentação de linha são traduzidas para nova linha na entrada. Na saída ocorre o inverso: caracteres de nova linha são convertidos em retorno de carro/alimentação de linha. Em arquivos binários não ocorre nenhuma tradução.

Caso tudo corra bem, a função fopen devolve um ponteiro de arquivo, caso ocorra algum problema ela devolve NULL.

Para abrir um arquivo texto chamado "teste" para escrita você poderia escrever assim:

FILE *arquivo;

arquivo = fopen("teste","w");

Porém, é recomendável sempre testar se o arquivo foi aberto sem problemas. Assim, sempre que for abrir um arquivo, você deve usar um código parecido com este:

FILE *arquivo;

if((arquivo = fopen("teste","w")) == NULL)
  {
    printf("Erro ao abrir arquivo!!!\n");
    exit(1);
  }

Este tipo de teste detectará algum problema tipo disco cheio ou protegido contra gravação antes que seu programa tente gravar nele.

O número máximo de arquivos que pode ser aberto ao mesmo tempo é definido pela macro FOPEN_MAX, normalmente definida em stdio.h. Confira se é o caso do seu compilador.

11.5 Fechando um arquivo

Para fechar uma stream você deve usar a função fclose( ).

Ela escreve qualquer dado que ainda permanece no buffer de disco no arquivo e o fecha em nível de sistema operacional. Uma falha ao fechar uma stream pode provocar problemas tipo perda de dados, arquivos destruídos e erros intermitentes em seu programa. fclose também libera o bloco de controle de arquivo associado à stream deixando-o disponível para reutilização. Como, normalmente, há um limite do sistema operacional para o número de arquivos abertos ao mesmo tempo, você deve fechar um arquivo antes de abrir outro.

A sintaxe de fclose é:

fclose(ARQUIVO);

Onde ARQUIVO é o ponteiro de arquivo devolvido por fopen quando esta abriu o arquivo. Caso o fechamento do arquivo ocorra sem problemas, fclose retorna zero. Qualquer outro valor indica erro. Erros possíveis são floppy drive sem disquete ou disco cheio.

11.6 Escrevendo e lendo caracteres

Para escrever um caracter num arquivo aberto você pode usar duas funções: putc( ) ou fputc( ). Elas são identicas. Existem as duas para preservar a compatibilidade com versões mais antigas do C. É lógico que para escrever num arquivo este deve ter sido aberto num modo que permita a escrita.

Veremos putc( ). Sua sintaxe é:

putc(CARACTER,ARQUIVO);

Onde CARACTER é o caracter a ser escrito no arquivo e ARQUIVO é um ponteiro de arquivo.

Se ocorrer tudo bem, a função retorna o caracter escrito, caso contrário ela retorna EOF.

Para ler um caracter temos também duas funções: getc( ) e fgetc( ). Existem duas também pelo motivo da compatibilidade com versões mais antigas da linguagem C. O arquivo deve ter sido aberto num modo que permita a leitura.

Veremos getc( ). Sua sintaxe é:

getc(ARQUIVO);

Onde ARQUIVO é um ponteiro de arquivo.

Quando o final do arquivo é alcançado a função devolve EOF.

Para ler o conteúdo de um arquivo você poderia usar um trecho de código parecido com:

do
  {
     caracter = getc(arquivo);
  }
while(caracter != EOF);

Sendo caracter uma variável char e arquivo uma variável ponteiro para uma estrutura FILE.

É importante observar que getc também devolve EOF caso ocorra algum erro.

11.7 Programa que lê e exibe o conteúdo de um arquivo texto

/* lendo e exibindo o conteúdo de um arquivo texto */

#include <stdio.h>

int main(int argc, char *argv[])
  {
    char caracter;
    FILE *arquivo;    

    if(argc < 2)
      {
        printf("\nErro: Digite o nome do arquivo !!!\n\n");
        exit(1);
      }

    printf("\n%s\n\n",argv[1]);

    if((arquivo = fopen(argv[1],"r")) == NULL)
      {
        printf("Erro ao abrir arquivo!!!\n\n");
        exit(1);
      };

    do
      {
        caracter = getc(arquivo);
        putchar(caracter);
      }
    while(caracter != EOF);

    printf("\n\n");

    fclose(arquivo);

    return(0);
  }

Observe que este código exibe também o caracter EOF. Um bom exercício é reescrever este código de modo que este caracter não seja exibido.

11.8 Programa que escreve caracteres num arquivo

/* escrevendo caracteres num arquivo */

#include <stdio.h>

int main(int argc, char *argv[])
  {
    FILE *arquivo;
    char caracter;

    if(argc < 2)
      {
        printf("\nErro: Digite o nome do arquivo !!!\n\n");
        exit(1);
      }

    if((arquivo = fopen(argv[1],"w")) == NULL)
      {
        printf("Erro ao abrir arquivo!!!\n\n");
        exit(1);
      }

    do
      {
        caracter = getchar();
        putc(caracter,arquivo);
      }
    while(caracter != '$');

    fclose(arquivo);

    printf("\nGravado com sucesso em %s\n\n",argv[1]);

    return(0); 
  }

11.9 Verificando o final de um arquivo binário

Quando manipulando dados binários um valor inteiro igual a EOF pode ser lido por engano. Isso poderia fazer com que fosse indicado o fim de arquivo antes deste ter chegado. Para resolver este problema C inclui a função feof( ) que determina quando o final de um arquivo foi atingido. Ela tem a seguinte sintaxe:

feof(ARQUIVO);

onde ARQUIVO é um ponteiro de arquivo. Esta função faz parte de stdio.h e devolve verdadeiro caso o final de arquivo seja atingido; caso contrário ela devolve 0.

Para ler um arquivo binário você poderia usar o seguinte trecho de código:

while(!feof(arquivo))
  caracter = getc(arquivo);

11.10 Programa que copia arquivo

/* programa que copia arquivo */

#include <stdio.h>

int main(int argc, char *argv[])
  {
    FILE *original,*copia;
    char caracter;

    if(argc < 3)
      {
        printf("\nSintaxe correta:\n\n");
        printf("copiar ARQUIVO_ORIGEM ARQUIVO_DESTINO\n\n");
        exit(1);
      }

    
    while(argv[1])
      {
         if(*argv[1] == *argv[2])
           break;
         printf("\nO nome do arquivo original não pode ser igual ao da\
 cópia.\n\n");
         exit(1);
      };


    if((original = fopen(argv[1],"rb")) == NULL)
      {
        printf("\nErro ao abrir o arquivo original.\n\n");
        exit(1);
      }             

    if((copia = fopen(argv[2],"wb")) == NULL)
      {
        printf("\nErro ao abrir o arquivo cópia.\n\n");
        exit(1);
      }

    while(!feof(original))
      {
        caracter = getc(original);
        if(!feof(original))
          putc(caracter,copia);
      }

    fclose(original);
    fclose(copia);
              
    printf("\n%s copiado com sucesso com o nome de %s.\n\n",argv[1],argv[2]);

    return(0);
  }

11.11 Escrevendo e lendo strings

Para escrever e ler strings em um arquivo use as funções fputs( ) e fgets( ), cujos protótipos encontram-se em stdio.h.

fputs( ) escreve uma string na stream especificada, sua sintaxe é:

fputs(STRING,ARQUIVO);

onde ARQUIVO é um ponteiro de arquivo. Caso ocorra algum erro esta função retorna EOF.

fgets( ) lê uma string da stream especificada. Sua sintaxe é:

fgets(STRING,TAMANHO,ARQUIVO);

Ela lê STRING até que um caractere de nova linha seja lido ou que TAMANHO - 1 caracteres tenham sido lidos. Se uma nova linha é lida ela será parte da string. A string resultante terminará em nulo. Caso ocorra tudo bem esta função retornará um ponteiro para STRING, caso contrário, retornará um ponteiro nulo.

11.12 Programa que escreve strings num arquivo

/* Programa que escreve strings num arquivo.
 *
 * Para encerrar o programa o usuário deverá inserir uma
 * linha em branco. 
 * 
 * Como gets() não armazena o caractere de nova linha,
 * é adicionado um antes da string ser gravada no arquivo.
 * Isto é feito para que a string possa ser lida, posteriormente,
 * com fgets() já que esta função lê a string até que seja
 * encontrado um caracter de nova linha.
 */

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
  {
   char string[80];
   FILE *arquivo;

    if(argc < 2)
      {
        printf("\nErro: Digite o nome do arquivo !!!\n\n");
        exit(1);
      }
       

    if((arquivo = fopen(argv[1],"w")) == NULL)
      {
        printf("Erro ao abrir arquivo!!!\n\n");
        exit(1);
      }

    do
      {
        gets(string);
        strcat(string,"\n");
        fputs(string,arquivo);
      }
    while(*string != '\n');
 
    fclose(arquivo);

    return(0);
  }

11.13 Apontando para o início do arquivo

Para apontar para o início do arquivo use a função rewind( ), cujo protótipo está no arquivo de cabeçalho stdio.h. Sua sintaxe é:

rewind(ARQUIVO);

sendo ARQUIVO um ponteiro de arquivo.

11.14 Verificando se a operação com o arquivo produziu um erro

Para determinar se uma operação com o arquivo produziu um erro use a função ferror( ). Seu protótipo está em stdio.h e sua sintaxe é:

ferror(ARQUIVO);

sendo ARQUIVO um ponteiro de arquivo. Esta função retorna verdadeiro se ocorreu um erro durante a última operação com o arquivo, caso contrário retorna falso. Como cada operação modifica a condição de erro, ela deve ser chamada logo após cada operação realizada com o arquivo.

11.15 Apagando um arquivo

Para apagar uma arquivo use a função remove( ). Ela faz parte de stdio.h e sua sintaxe é:

remove(ARQUIVO);

sendo ARQUIVO um ponteiro de arquivo.

Exemplo:

/* Apagando um arquivo */

#include <stdio.h>
#include <ctype.h>

int main(int argc,char *argv[])
  {
    FILE * arquivo;
    char opcao[5];

    if(argc != 2)
      {
        printf("Erro !!! \n");
        printf("Sintaxe correta: apagar ARQUIVO\n");
        exit(1);
      }    
    
    printf("Deseja realmente apagar o arquivo %s (S/N)?",argv[1]);
    gets(opcao);

    if(toupper(*opcao) == 'S')
      if(remove(argv[1]))
        {
          printf("Erro ao tentar apagar arquivo.\n");
          exit(1);
        }
      else
        printf("Arquivo apagado com sucesso.\n");

    return(0);
  }

11.16 Renomeando ou Movendo um arquivo

Para renomear um arquivo use a função rename( ). Ela está em stdio.h e sua sintaxe é:

rename(NOME_ANTIGO, NOVO_NOME);

onde NOME_ANTIGO e NOVO_NOME são ponteiros string. Se a função for bem sucedida ela retornará zero, caso contrário, retornará um valor diferente de zero.

Esta mesma função serve para mover um arquivo. Basta incluir a nova localização como parte do NOVO_NOME do arquivo. Observe o exemplo abaixo:

/* renomeando ou movendo um arquivo */

#include <stdio.h>

int main(int argc,char *argv[])
  {

    if(argc != 3)
      {
        printf("Erro !!! \n");
        printf("Sintaxe correta: renomear NOME_ANTIGO NOVO_NOME\n");
        exit(1);
      }

    if(rename(argv[1],argv[2]))
      printf("Erro ao renomear arquivo!\n");

    return(0);
  }

Este programa renomeia um arquivo. Porém, se você especificar um outro local para o novo nome do arquivo, este, além de ser renomeado, será movido. Crie um arquivo chamado teste em seu diretório de usuário e, após compilar o exemplo acima com o nome de renomear, digite o seguinte comando:

$ renomear teste teste123

liste o conteúdo do diretório e você verá que o arquivo foi renomeado. Agora crie um diretório chamado lixo e digite o comando:

$ renomear teste123 lixo/teste456

dê uma checada e você verá que o arquivo teste123 não existe mais no diretório atual, mas em lixo foi criado o arquivo teste456, mostrando que teste123 foi movido e renomeado.

11.17 Esvaziando uma stream

Para esvaziar o conteúdo de uma stream aberta para saída use a função fflush( ). Sua sintaxe é:

fflush(ARQUIVO);

sendo ARQUIVO um ponteiro de arquivo. Ela escreve o conteudo do buffer para o arquivo passado como argumento. Se for passado um valor nulo, todos os arquivos abertos para saída serão descarregados. Se tudo ocorrer bem fflush retornará zero, indicando sucesso. Caso contrário, devolverá EOF.

11.18 Escrevendo e lendo tipos de dados definidos pelo usuário

Veremos mais a frente que C permite que o usuário crie seus próprios tipos de daos. Este tipos de dados são estruturas compostas de tipos de dados simples e com estas estruturas podemos construir registros.

Para escrever e ler estas estruturas podemos usar as funções fread( ) e fwrite( ). Elas são definidas em stdio.h.

A sintaxe de fread( ) é:

fread(VARIÁVEL,TAMANHO,QUANTIDADE,ARQUIVO);

onde:

A sintaxe para fwrite( ) é idêntica, com a exceção que VARIÁVEL é o endereço da variável com os dados a serem escritos no arquivo.

O ponteiro de arquivo "ARQUIVO" deve ser aberto em modo binário, para podermos ler e escrever qualquer tipo de informação. Também deve ser aberto de acordo com a operação a ser feita (leitura ou escrita).

fread devolve o número de itens lidos. Esse valor poderá ser menor que QUANTIDADE se o final do arquivo for atingido ou ocorrer um erro.

fwrite devolve o número de itens escritos. Esse valor será igual a QUANTIDADE a menos que ocorra um erro.

Abaixo segue um exemplo do uso de fwrite. Vamos escrever alguns dados num arquivo.

/* Usando fwrite para escrever dados num arquivo */

#include <stdio.h>

int main()
  {
    FILE *arquivo;
    char nome[5]="samu";
    int idade=34;
    float altura=1.82;

    if((arquivo = fopen("samu.dat","wb")) == NULL)
      {
        printf("Erro ao abrir arquivo!!!\n\n");
        exit(1);
      }

    fwrite(&nome,sizeof(nome),1,arquivo);
    fwrite(&idade,sizeof(idade),1,arquivo);
    fwrite(&altura,sizeof(altura),1,arquivo);

    fclose(arquivo);

    return(0);
  }

Agora veremos um exemplo com o uso de fread que lerá o arquivo "samu.dat" criado no exemplo acima:

/* Usando fread para ler dados de um arquivo */

#include <stdio.h>

int main()
  {
    FILE *arquivo;
    char nome[5];
    int idade;
    float altura;

    if((arquivo = fopen("samu.dat","rb")) == NULL)
      {
        printf("Erro ao abrir arquivo!!!\n\n");
        exit(1);
      }

    fread(&nome,sizeof(nome),1,arquivo);
    fread(&idade,sizeof(idade),1,arquivo);
    fread(&altura,sizeof(altura),1,arquivo);

    printf("nome  : %s\n",nome);
    printf("idade : %d\n",idade);
    printf("altura: %.2f\n",altura);

    fclose(arquivo);

    return(0);
  }

Embora não tenha sido feito nestes dois exemplos, é interessante, em programas maiores, a análise do retorno de fread e fwrite para ver se não ocorreram erros. Isto pode ser feito com uma instrução deste tipo:

if(fread(&nome,sizeof(nome),1,arquivo) != 1)
  printf("Erro de leitura.\n");

11.19 Apontando para uma posição específica dentro do arquivo

Você pode apontar para um byte específico dentro do arquivo movimentando o indicador de posição. Isto pode ser feito com o uso da função fseek( ),cuja sintaxe é:

fseek(ARQUIVO, NÚMERO_DE_BYTES, ORIGEM);

onde ARQUIVO é um ponteiro de arquivo aberto anteriormente, NÚMERO_DE_BYTES é a quantidade de bytes que o indicador de posição será movimentado e ORIGEM é a partir de onde o movimento do indicador de posição iniciará.

ORIGEM deve ser uma das seguintes macros:

	SEEK_SET para a origem no início do arquivo
  
	SEEK_CUR para a origem na posição atual do indicador de posição

	SEEK_END para a origem no final do arquivo

estas macros estão definidas em stdio.h.

NÚMERO_DE_BYTES deve ser usado em conjunto com sizeof para que possamos acessar os tipos de dados pré-definidos. Por exemplo, digamos que criamos um tipo de dado chamado "ficha", onde armazenamos os dados de um livro como título, autor, editora, etc... e escrevemos vários dados em um arquivo. Se quisermos apontar o indicador de posição para o quinto registro deste arquivo deveremos usar algo como:

fseek(arquivo,4*sizeof(struct ficha),SEEK_SET);

11.20 Entrada e saída formatadas direcionadas para arquivos

Existem as funções fprintf( ) e fscanf( ) que são semelhantes a printf e a scanf mas que direcionam os dados para arquivos. Abaixo você pode ver a sintaxe destas funções:

fprintf(ARQUIVO,"ESPECIFICADOR",VARIÁVEL);

fscanf(ARQUIVO,"ESPECIFICADOR",VARIÁVEL);

onde ARQUIVO é um ponteiro de arquivo aberto para onde são direcionados os resultados das funções.

Abaixo segue um exemplo do uso destas funções:

/* exemplo do uso de fscanf e fprintf
 * este programa lê uma string do teclado e a escreve num arquivo texto
 * compilado com o nome de adtexto */

#include <stdio.h>

int main()
  {
    FILE *arquivo;
    char string[80];
    
    if((arquivo = fopen("adtexto.txt","w")) == NULL)
      {
        printf("Erro ao abrir o arquivo!\n");
        exit(1);
      }
    
    printf("Exemplo do uso de fscanf e fprintf\n");
    printf("Digite uma string\n\n");
    fscanf(stdin,"%s",string); /* lê string do teclado */
    fprintf(arquivo,"%s",string); /* escreve string no arquivo */
    
    fclose(arquivo);
      
    return(0);
  }

Embora sejam uma opção atraente para ler e escrever dados em arquivos, estas funções devem ser evitadas pois trabalham com dados ASCII e não binários o que ocasiona uma perda de desempenho no programa. É preferível o uso de fread e fwrite.

11.21 Streams padrão

Quando um programa em linguagem C é iniciado são abertas três streams: stdin, stdout e stderr.

stdin define a entrada padrão do sistema, normalmente o teclado.

stdout define a saída padrão do sistema, normalmente o monitor.

stderr define a saída padrão dos erros, normalmente também é o monitor.

Estas streams são ponteiros de arquivos e podem ser redirecionadas. Assim, nas funções que você utiliza ponteiros de arquivos para entrada e saída de dados você pode muito bem usar estas streams de modo ao seu programa receber dados do teclado e escrever no monitor. Isto foi mostrado no exemplo da seção anterior na linha;

fscanf(stdin,"%s",string); /* lê string do teclado */

onde o programa leu a variável string do teclado através da streams padrão stdin.

Porém esteja consciente que estas streams não são variáveis e não podem receber um valor. Ou seja, você não pode abrí-las com fopen.

Quando o programa é encerrado estas streams são fechadas automaticamente, do mesmo jeito que foram criadas, você não deve nunca tentar abrí-las ou fechá-las.


[ Voltar ] [ Índice ] [ Avançar ]
1