A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Laboratório de Programação Prof. Oscar Luiz Monteiro de Farias

Apresentações semelhantes


Apresentação em tema: "Laboratório de Programação Prof. Oscar Luiz Monteiro de Farias"— Transcrição da apresentação:

1 Laboratório de Programação Prof. Oscar Luiz Monteiro de Farias

2 Capítulo 7 Biblioteca Padrão & Entrada/Saída

3 Biblioteca padrão (1) Um conjunto de funções que provê uma série de serviços: input e output, manipulação de cadeias de caracteres, gerência de espaço de armazenamento, funções matemáticas, entre outros. O padrão ANSI define com precisão as funções da biblioteca padrão. Os programas em C que limitam suas interações como sistema às facilidades fornecidas pela biblioteca padrão são portáveis para as máquinas em que o C padrão ANSI esteja instalado.

4 Biblioteca padrão (2) As propriedades das funções da biblioteca estão especificadas em mais de uma dúzia de arquivos headers, incluindo,,, entre outros. A biblioteca padrão encontra-se descrita no apêndice B do livro texto (The C Programming Language, 2nd edition) e no ANSI C Language and Libraries Reference Manual(The C Programming Language, 2nd edition)ANSI C Language and Libraries Reference Manual As facilidades de entrada e saída não fazem parte da linguagem C, mas são implementadas, segundo um modelo de entrada e saída simplificado, via biblioteca padrão.

5 Entrada e saída (E/S) padrão (1) A E/S se dá através de fluxos de texto. Um fluxo de texto consiste de uma seqüência de linhas. Cada linha termina com um caracter de nova linha (''\n''). O término do fluxo é sinalizado com EOF (end of file). Se o sistema não opera dessa forma, a biblioteca faz o que for necessário para que tudo esteja de acordo com o modelo. O mecanismo de entrada mais simples é ler um caracter de cada vez da entrada padrão, normalmente o teclado, com a função getchar: int getchar(void)

6 Entrada e saída (E/S) padrão (2) getchar retorna o próximo caracterda entrada toda vez que é invocada, ou EOF quando encontrar o fim de arquivo. A constante simbólica EOF é definida em Em muitos ambientes a entrada padrão (teclado) pode ser redirecionada para um arquivo através da convenção <. Se prog usa getchar, prog < infile fará que prog leia caracteres do arquivo infile.

7 Entrada e saída (E/S) padrão (2) A cadeia < infile não é incluída nos argumentos da linha de comando em argv. A troca da entrada é também invisível se a entrada vem de outro programa via o mecanismo pipe: em alguns sistemas otherprog | prog Executa os dois programas otherprog e prog, e canaliza (direciona) a saída padrão de otherprog para a entrada padrão de prog.

8 Entrada e saída (E/S) padrão (3) A função int putchar(int) é usada para saída. putchar(c) coloca o caracter c na saída padrão, que, por default, é a tela. putchar retorna o caracter escrito, ou EOF em caso de erro. A saída pode ser direcionada para um arquivo com: >filename Se prog usa putchar prog >outfile Irá escrever a saída padrão em outfile.

9 Entrada e saída (E/S) padrão (4) A saída produzida por printf também é enviada para a saída padrão. Chamadas a putchar e printf podem ser intercaladas – a saída aprece na ordem em que as chamadas foram realizadas. Cada arquivo fonte que se refere a uma função de entrada/saída da biblioteca padrão deve conter a linha #include antes de sua primeira referência.

10 Entrada e saída (E/S) padrão (5) Quando um nome é delimitado por é feita uma busca pelo header em um conjunto padrão de locais (em sistemas unix, no diretório /usr/include). Várias ''funções'' como getchar e putchar em e tolower em são normalmente macros, para se evitar o overhead de uma chamada de função por caractere.

11 Saída formatada – printf (1) int printf(char *format, arg1, arg2,...); printf converte, formata, e imprime seus argumentos na saída padrão, sob o controle de format. printf retorna o número de caracteres impressos. A cadeia format contém dois tipos de objetos: i) caracteres comuns, que são copiados no fluxo de saída; ii) especificações de conversão, cada uma delas causando uma conversão e impressão do próximo argumento sucessivo de printf. Cada especificação de conversão inicia-se com um % e termina com um caracter de conversão.

12 Saída formatada – printf (2) Entre o % e o caracter de conversão pode haver, em ordem: Um sinal ''-'', que especifica ajustamento à esquerda do argumento convertido. Um número, que especifica a largura mínima do campo. O argumento convertido será impresso em um campo com pelo menos esta largura. Se necessário ele será preenchido à esquerda (ou à direita, se o ajustamento à esquerda for solicitado) para compor a largura do campo. Um ponto ''.'', que separa a largura do campo de sua precisão. Um número, a precisão, que especifica o número máximo de caracteres a ser impresso em uma cadeia, ou o número de dígitos após o ponto decimal de um valor em ponto flutuante, ou o número mínimo de dígitos para um inteiro. Um h se o inteiro é para ser impresso como short, ou l (letra ele), se como long. Se o caracter após o % não for uma especificação de conversão, o comportamento é indefinido.

13 Saída formatada – printf (3)

14 Saída formatada – printf (4) Uma largura ou precisão pode ser especificada por *; o valor é computado convertendo-se o próximo argumento (que deve ser um int) Por exemplo, para imprimir no máximo max caracteres da cadeia s printf("%.*s", max, s); A tabela a seguirmostra uma série de especificações para imprimir ''hello, world'' (12 caracteres). Foram colocados : ao redor de cada campo para que se possa ver a sua extensão.

15 Saída formatada – printf (5) printf usa seu primeiro argumento para decidir quantos argumentos virão a seguir e quais os seus tipos.

16 Saída formatada – printf (6) A função sprintf faz as mesmas conversões que printf, mas armazena a saída em uma cadeia de caracteres. int sprintf(char *string,char *format, arg1, arg2,...); sprintf formata os argumentos em arg1, arg2, …, de acordo com as especificações em format. A cadeia deve ter tamanho suficiente para receber o resultado.

17 Lista de argumentos de tamanho variável(1) Ver prog66-chap07-pg127.c Implementação de uma versão mínima de printf, mostrando como escrever uma função minprintf, que processa uma lista de argumentos de tamanho variável de forma portátil. O interesse principal é no processamento de argumentos de tamanho variável. Assim, minprintf processará a cadeia de formato e os argumentos e invocará a printf real, para realizar as conversões de formato.

18 Lista de argumentos de tamanho variável(2) A declaração apropriadada para printf é: int printf(char *fmt,...) significa que o número e tipos de argumentos podem variar. A declaração … só pode aparecer ao final de uma lista de argumentos. minprintf será declarada como: void minprintf(char fmt, …) O artifício utilizado é como minprintf percorre a lista de argumentos enquanto a lista sequer possui um nome.

19 Lista de argumentos de tamanho variável(3) O header padão contém um conjunto de definições de macros que define como percorrer uma lista de argumentos. A implementação desse header varia entre máquinas, porém sua interface é uniforme. O tipo va_list é usado para declarar uma variável que irá se referir a cada argumento, quando de sua vez. Em minprintf, esta variável é chamada ap, significando argument pointer.

20 Lista de argumentos de tamanho variável(4) A macro va_start inicializa ap para apontar para o primeiro argumento não nomeado. Ela deve ser invocada uma vez, antes que ap seja usado. Deve existir ao menos um argumento nomeado. O argumento final nomeado é usado por va_start para dar início. Cada invocação de va_arg retorna um argumento e incrementa ap para o próximo; va_arg usa um nome de tipo para determinar o tipo a retornar e o tamanho do passo a executar. Finalmente, va_end realiza qualquer tarefa final necessária. va_end deve ser chamada antes que a função retorne.

21 Entrada formatada – scanf (1) A função scanf é a entrada análoga à printf, fornecendo muitas das facilidades de conversão no sentido inverso. int scanf(char *format,...) scanf lê caracteres da entrada padrão, os interpreta, segundo a especificação em format, e armazena os resultados via osargumentos restantes. O argumento format é descrito a seguir. Os outros argumentos, cada qual devendo ser um pointer, indicam aonde as entradas convertidas correspondentes devem ser armazenadas.

22 Entrada formatada – scanf (2) scanf pára quando termina a sua cadeia de formato, ou quando alguma entrada deixar de casar com a especificação de controle. scanf retorna o número de ítens casados e atribuídos com sucesso, ou EOF para indicar final do arquivo de entrada, ou 0 (zero) para indicar que o próximo caracter de entrada não combina com a especificação correspondente na cadeia format. A cadeia format contém especificações de conversão que são usadas para controlar a conversão de entrada.

23 Entrada formatada – scanf (3) A cadeia format pode conter: i) Espaços ou tabulações, que são ignorados. ii) Caracteres comuns (não %), que devem combinar com o próximo caracter não espaço do fluxo de entrada. iii) Especificações de conversão, consistindo do caracter %, um caracter opcional de supressão de atribuição *, um número opcional especificando o tamanho máximo do campo, um h, l ou L opcionais indicando o tamanho do destino, e um caracter de conversão. Uma especificação de conversão direciona a conversão do próximo campo de entrada.

24 Entrada formatada – scanf (4) Normalmente o resultado é armazenado na variável apontada pelo argumento correspondente (&name). Todavia, * sinaliza para que nenhuma atribuição seja efetuada (salta o campo de entrada). Define-se um campo de entrada como uma cadeia de caracteres sem espaços; o campo estende-se até o próximo caracter de espaço, ou até que a largura do campo, se especificada, termine. scanf lerá além dos limites de linha para encontrar a sua entrada, pois os caracteres de new line ('\n') são considerados espaços (White space characters are blank, tab, newline, carriage return, vertical tab, and formfeed). A especificação de conversão direciona a conversão do próximo campo de entrada.

25 Entrada formatada – scanf (5)

26 Entrada formatada – scanf (6) Os caracteres de conversão d, i, o, u, e x podem ser precedidos por h para indicar que um pointer para short ao invés de int aparece na lista de argumentos, ou por l (letra ele) para indicar que um pointer para long aparece na lista de argumentos. Similarmente os caracteres de conversão e, f e g podem ser precedidos por l para indicar que um pointer para double ao invés de float aparece na lista de argumentos.

27 Entrada formatada – scanf (7) A conversão de entrada da calculadora elementar do capítulo 4 pode ser realizada com scanf. Ver prog67-chap07-pg129.c Supor que se deseja ler linhas de entrada com datas com o formato 25 dez 1988 O trecho de código do programa seria algo como: int day, year; char monthname[20]; … scanf("%d %s %d", &day, monthname, &year);

28 Entrada formatada – scanf (8) Caracteres literais podem aparecer no argumento format de scanf; eles devem corresponder aos mesmos caracteres na entrada. Assim, pode-se ler datas no formato mm/dd/yy com os comandos: int day, month, year; scanf("%d/%d/%d", &month, &day, &year); scanf ignora blanks e tabs em sua cadeia format. scanf salta espaços (blanks, tabs, newlines, etc.) à medida que procura valores de entrada.

29 Entrada formatada – scanf (9) Para ler uma entrada cujo formato não seja fixo é melhor ler uma linha de cada vez e depois separar os campos com scanf. Exemplo: supor que se deseja ler linhas com uma data em quaiquer um dos formatos dos dois slides anteriores:

30 Entrada formatada – scanf (10) Invocações a scanf podem ser intercaladas com invocações a outras funções de entrada. A próxima invocação a qualquer função de entrada começará lendo o primeiro caracter não lido por scanf. A função sprintf faz as mesmas conversões que printf, porém armazena a saída em uma cadeia de caracteres: int sprintf(char *string, char *format, arg1, arg2,...); A cadeia deve ser grande o suficiente para armazenar o resultado. ATENÇÃO: os argumentos para scanf e sscanf devem ser pointers (&name).

31 Acesso a arquivos (1) Possibilita a leitura e gravação em arquivos que não sejam a entrada e saída padrão definidos automaticamente pelo sistema operacional. Em C, cada arquivo é simplesmente um fluxo (stream) sequencial de bytes. C não impõe qualquer tipo de estrutura aos arquivos. É preciso que os arquivos nomeados e reconhecidos pelo sistema operacional sejam conectados aos comandos em C que leiam e gravem dados nos arquivos. As regras são triviais. Antes que possa ler ou gravar, em um arquivo, o mesmo deve ser aberto (opened) de modo apropriado. Quando um arquivo é aberto, um fluxo (stream) sequencial de bytes é associado ao mesmo. Um arquivo deve ser aberto com a função da biblioteca padrão FILE *fopen(char *name, char *mode);

32 Acesso a arquivos (2) fopen usa um nome externo (e.g., myfile.txt), faz alguma tarefa inicial, negocia com o sistema operacional (detalhes em que não estamos interessados) e retorna um pointer a ser usado em leituras ou gravações posteriores no arquivo. Este pointer, chamado apontador de arquivo (file pointer) aponta para uma estrutura que contém informações sobre o arquivo (file descriptor e um file control block), tais como: o local de um buffer, a posição do caracter corrente no buffer, se o arquivo está sendo lido ou gravado, e se foram encontrados erros ou o fim de arquivo. Os usuários não precisam saber os detalhes, pois as definições são obtidas de incluem a declaração de uma estrutura denominada FILE.

33 Acesso a arquivos (3) As declarações necessarias seriam: FILE *fp; FILE *fopen(char *name, char *mode); significando que fp é um pointer para um FILE (arquivo). FILE é um nome de tipo, definido com um typedef e não uma etiqueta de estrutura. Detalhes da implementação de fopen em um sistema UNIX podem ser encontrados na seção 8.5).

34 Acesso a arquivos (4) A chamada a fopen em um programa seria: fp = fopen(name, mode); O primeiro argumento de fopen – name - é uma cadeia de caracteres contendo o nome do arquivo. O segundo argumento - mode - também é uma cadeia de caracteres, que indica como se pretende usar o arquivo. Os modos permitidos incluem: leitura - read ("r"), gravação - write ("w"), e anexação - append ("a"). Alguns sistemas distingüem arquivos de texto e binários. Para estes últimos um ''b'' deve ser incluído na cadeia mode.

35 Acesso a arquivos (5) Se um arquivo que não existe for aberto para escrita ou anexação, ele é criado, se possível. Abrir um arquivo já existente para gravação faz com que o conteúdo antigo seja descartado, enquanto que abrí-lo para anexação o preserva. Tentar ler um arquivo que não existe ocasiona um erro, assim como tentar ler um arquivo quando não se tem a necessária permissão. Em caso de erro fopen retorna NULL (pode-se identificar o erro de forma mais exata – veja final da seção 1 do apêndice B).

36 Acesso a arquivos (6) A função int fclose(FILE *fp) é o inverso de fopen. Ela encerra a conexão entre o apontador de arquivo (pointer para FILE) e o nome externo que foi estabelecido por fopen, liberando o apontador de arquivo para outro arquivo. A maior parte dos sistemas operacionais tem um limite para o número de arquivos que um sistema pode abrir simultaneamente e é uma boa política liberar os apontadores para FILE, quando não mais são necessários. Um outro motivo é que fclose esvazia o buffer de saída. fclose é chamado automaticamente para cada arquivo aberto quando um programa termina de forma normal.

37 Acesso a arquivos (7) Quando um programa em C é iniciado, o ambiente do sistema operacional é responsável por abrir três arquivos e fornecer pointers para os mesmos. Esses arquivos são: a entrada padrão (stdin), a saída padrão (stdout) e o erro padrão (stderr). Normalmente stdin é conectado ao teclado, stdout e stderr à tela. stdin e stdout podem ser redirecionados para arquivos ou pipes.

38 Operações sobre arquivos (1) As operações a seguir lidam com operações sobre arquivos. O tipo size_t é o tipo unsigned integer produzido pelo operador sizeof.

39 Operações sobre arquivos (2)

40 Operações sobre arquivos (3)

41 Saída formatada em arquivos (1) int fprintf(FILE *stream, const char *format, …) fprintf converte e grava a saída para stream sob o controle de format. O valor retornado é o número de caracteres gravados ou negativo, se houver erro. A cadeia format contém dois tipos de objetos: i) caracteres normais, que são copiados para o fluxo (stream) de saída; ii) especificações de conversão, cada uma delas causando a conversão e impressão do próximo argumento sucessivo em fprintf. Cada especificação de conversão inicia-se com o caracter % e termina com um caracter de conversão.

42 Saída formatada em arquivos (2) Entre o % e o caracter de conversão pode haver, em ordem:

43 Saída formatada em arquivos (3)

44 Saída formatada em arquivos (4) Tamanho ou precisão ou ambos podem ser especificados por *, quando o valor é computado convertendo-se o(s) próximo(s) argumento(s), que deve(m) ser int. Os caracteres de conversão e os seus significados são mostrados na Table B.1. Se o caracter após o % não for um caracter de conversão, o comportamento será indefinido.

45 Saída formatada em arquivos (5)

46 Saída formatada em arquivos (6)

47 Saída formatada em arquivos (7) int printf(const char *format,...) printf(...) é equivalente a fprintf(stdout,...). int sprintf(char *s, const char *format,...) sprintf comporta-se como printf exceto que a saída é impressa na cadeia de caracteres s, terminada com '\0'. s deve ser grande o suficiente para conter o resultado. O contador de retorno (número de caracteres impressos) não inclui o '\0'.

48 Saída formatada em arquivos (8) int vprintf(const char *format, va_list arg) int vfprintf(FILE *stream, const char *format, va_list arg) int vsprintf(char *s, const char *format, va_list arg) As funções vprintf, vfprintf, e vsprintf são equivalentes às funções printf correspondentes, exceto que a lista de argumentos variáveis é substituída por arg, que foi inicializado pela macro va_start e eventualmente por chamadas a va_arg. Veja a discussão de na Seção B.7.

49 Entrada formatada em arquivos(1) int fscanf(FILE *stream, const char *format,...) fscanf lê de stream sob o controle de format, e atribui os valores convertidos aos argumentos subseqüentes, cada um dos quais deve ser um pointer. fscanf retorna quando format tiver terminado. fscanf retorna EOF se ocorrer um fim de arquivo ou zero se ocorrer um erro antes de alguma conversão, caso contrário, retorna o número de ítens de entrada convertidos e atribuídos com sucesso.

50 Entrada formatada em arquivos(2) A cadeia format pode conter: i) Espaços ou tabulações, que são ignorados. ii) Caracteres comuns (não %), que devem combinar com o próximo caracter não espaço do fluxo de entrada. iii) Especificações de conversão, consistindo do caracter %, um caracter opcional de supressão de atribuição *, um número opcional especificando o tamanho máximo do campo, um h, l ou L opcionais indicando o tamanho do destino, e um caracter de conversão. Uma especificação de conversão direciona a conversão do próximo campo de entrada.

51 Entrada formatada em arquivos(3) Normalmente o resultado é armazenado na variável apontada pelo argumento correspondente (&name). Todavia, * sinaliza para que nenhuma atribuição seja efetuada (salta o campo de entrada). Define-se um campo de entrada como uma cadeia de caracteres sem espaços; o campo estende-se até o próximo caracter de espaço, ou até que a largura do campo, se especificada, termine. fscanf lerá além dos limites de linha para encontrar a sua entrada, pois os caracteres de new line ('\n') são considerados espaços (White space characters are blank, tab, newline, carriage return, vertical tab, and formfeed). A especificação de conversão direciona a conversão do próximo campo de entrada.

52 Entrada formatada em arquivos(4)

53 Entrada formatada em arquivos(5)

54 Entrada formatada em arquivos(6) Os caracteres de conversão d, i, o, u, e x podem ser precedidos por h para indicar que um pointer para short ao invés de int aparece na lista de argumentos, ou por l (letra ele) para indicar que um pointer para long aparece na lista de argumentos. Similarmente os caracteres de conversão e, f e g podem ser precedidos por l para indicar que um pointer para double ao invés de float aparece na lista de argumentos,e por L se houver um pointer para um long double.

55 Entrada formatada em arquivos(7) int scanf(const char *format,...) scanf(...) é idêntica a fscanf(stdin,...). int sscanf(const char *s, const char *format,...) sscanf(s,...) é equivalente a scanf(...) exceto que os caracteres de entrada são originários da cadeia s.

56 Funções de E/S de caracteres (1)

57 Funções de E/S de caracteres (2)

58 Funções de E/S direta

59 Posicionamento de arquivo

60 Funções indicativas de erros (1) Muitas das funções na biblioteca padrão definem indicadores de estado quando ocorre um erro ou fim de arquivo. Estes indicatores podem ser estabelecidos e testados explicitamente. Adicionalmente, a expressão errno (declarada em ) pode conter um número de erro que fornece informação sobre o erro mais recente.

61 Funções indicativas de erros (2)

62 Exemplos de programas (1) Programa cat para concatenar arquivos e imprimí- los na saída padrão (tela). Ver prog68-chap07-pg132.c (cat) Observação: os apontadores de arquivo stdin e stdout são objetos do tipo FILE*. Todavia eles são constantes. Não tente atribuir nada aos mesmos.

63 Exemplos de programas (2) O tratamento de erros em cat não é ideal. Se não se puder ter acesso a um dos arquivos por alguma razão, o diagnóstico será impresso ao final da saída concatenada. Se a saída for para um outro arquivo, ou se for desviada para um outro programa por meio de um pipe, tal solução não é aceitável, pois a mensagem de erro não se tornaria visível na tela. Solução: Ver prog69-chap07-pg133.c A saída escrita em stderr aparece na tela, mesmo que a entrada padrão seja redirecionada.

64 Exemplos de programas (3) Os erros são sinalizados de dois modos: i) a saída de diagnóstico produzida por fprintf vai para stderr, de forma que será enviada à tela, ao invés de desaparecer em um arquivo de saída, ou ser enviada por um pipe para outro programa; ii) o programa usa a função exit da biblioteca padrão, que termina a execução de um programa, assim que é invocada. O código de retorno de exit é disponível a qualquer processo que tenha invocado o programa como um subprocesso.

65 Por convenção 0 indica um retorno normal e valores diferentes de zero, situações anormais. exit chama fclose para cada arquivo aberto, esvaziando qualquer saída que se encontre em buffers. Em main, return expr é equivalente a exit(expr), com a vantagem de poder ser invocada por outras funções. A função ferror retorna não zero se houver algum erro no fluxo de fp int ferror(FILE *fp) int feof(FILE *fp) retorna um valor diferente de zero se o indicador de fim de arquivo (EOF) para o fluxo (stream) estiver setado. Exemplos de programas (4)

66 Exemplos de programas (5) ¨AllStd¨ é um arquivo com informações sobre o conjunto de alunos de uma escola e que deveria estar ordenado em ordem crescente, por número de matrícula. Todavia, um estagiário errôneamente ordenou-o por ordem decrescente de matrícula. Faça um programa, em C, que crie um novo arquivo ¨AllStdOK¨, com os registros dos alunos da escola na ordem originalmente desejada, isto é, em ordem crescente por matrícula. Dado do problema: cada registro do arquivo ¨TodosEstudantes¨ é formado pelos campos da estrutura: struct ficha_pessoal { char matricula[9]; char cpf[11]; char nome[30]; } aluno; Ver programas ex-01-file.c e cria_arq.c (no diretório …/chap07)


Carregar ppt "Laboratório de Programação Prof. Oscar Luiz Monteiro de Farias"

Apresentações semelhantes


Anúncios Google