Laboratório de Programação - Exercício 25



Documentos relacionados
AULA 3 Alocação dinâmica de memória: Ponteiros

Linguagem C: strings. Prof. Críston Algoritmos e Programação

Aula 3/4: Vetores/Matrizes e Ponteiros

Referências. Programação de Computadores II. Cap. 7 Cadeias de Caracteres. Caracteres. Tópicos

Sistemas Operacionais e Introdução à Programação. Programação com linguagem C

1 Cálculo do valor à vista

Aula Extra. Depurador Code::Blocks. Monitoria de Introdução à Programação

MC Teste de Mesa e Comandos Repetitivos

1 Exercícios com ponteiros

1 Exercícios com ponteiros

Computação 2. Aula 8. Profª. Fabiany Arquivos

Linguagem C. Introdução à Programação C. Variáveis. Identificadores. Identificadores 12/03/2011 VARIÁVEIS E TIPOS DE DADOS

Aula 16: Manipulação de Arquivos em C

ESTRUTURAS CONDICIONAIS. Introdução à Ciência da ComputaçãoI Simone Senger de Souza

INTRODUÇÃO À PROGRAMAÇÃO II VARIÁVEIS COMPOSTAS HOMOGÊNEAS UNIDIMENSIONAIS

Universidade Federal de Uberlândia - UFU Faculdade de Computação - FACOM Lista de exercícios de programação em linguagem C. Exercícios: Structs

ESTRUTURAS CONDICIONAIS. Baseado nos slides de autoria de Rosely Sanches e Simone Senger de Souza

Tipos Abstratos de Dados (TAD)

21 Strings O que são strings? 21.2 Leitura de Strings. Ronaldo F. Hashimoto e Carlos H. Morimoto

Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria

Ponteiros e Tabelas. K&R: Capítulo 5

3. COMPILAÇÃO E ESTRUTURA BÁSICA DE UM PROGRAMA EM C

Funções em C. Lucas Ferrari de Oliveira Professor Adjunto. Linguagem de Programação Estruturada I. Universidade Federal do Paraná

Conversão Visualg à C++ Prof. Paulo Cesar F. de Oliveira, BSc, PhD

Linguagem de Programação C. Fluxo de Saída Padrão. Linguagem de Programação C. printf. Fluxo de Saída Padrão. Algoritmos e Lógica de Programação

BC1424 Algoritmos e Estruturas de Dados I Aula 02: Ponteiros, estruturas e alocação de memória

PROGRAMAÇÃO FUNÇÕES NA LINGUAGEM C

LÓGICA DE PROGRAMAÇÃO. PROFª. M.Sc. JULIANA H Q BENACCHIO

Estruturas Condicionais

Programação de Computadores II

FUNÇÕES EM C Material adaptado da profa Silvana Maria Affonso de Lara

Trabalho Prático II - Resta 1 Data de Entrega: Conferir no calendário!

Programação: Vetores

Introdução. Software Básico Aula 3. Prof. Dr. Rogério Vargas.

Reader e Writer para streams de caracteres (texto).

BC-0505 Processamento da Informação

1. Estrutura de Dados

Ciclo com Contador : instrução for. for de variável := expressão to. expressão do instrução

3.1 - Funções para manipular dados de entrada e saída padrão

Computação 2. Aula Profª. Fabiany Listas Duplamente Encadeadas

INF 1007 Programação II

Cláudio C. Rodrigues Faculdade da Computação - UFU

Algoritmos APRENDENDO A PROGRAMAR COM C#

ALGORITMOS AULA 01. Baseado nas aulas do Prof. Jorgiano Vidal

Programação de Computadores I. Linguagem C Função

Conceitos c++ Prof. Demétrios Coutinho INFORMÁTICA BÁSICA

Linguagem C Ficheiros Compilação Separada

INTRODUÇÃO À LINGUAGEM PASCAL PREFÁCIO

Lógica e Linguagem de Programação Convertendo um algoritmo em pseudocódigo para a linguagem C Professor: Danilo Giacobo

UNIVERSIDADE FEDERAL DO ESPÍRITO SANTO CENTRO UNIVERSITÁRIO NORTE DO ESPÍRITO SANTO

Ficheiros binários 1. Ficheiros binários

CONFIGURANDO SERVIDOR SAT SS-1000

PIP/CA - Programa Interdisciplinar de Pós-Graduação em Computação Aplicada da UNISINOS ALGORITMOS & ESTRUTURAS DE DADOS

Estruturas de Dados. Alguns dados não costumam ser tão simples assim... Podem ser compostos por vários dados distintos

Sistemas Distribuídos Capítulo 4 - Aula 5

Introdução. Algoritmos

Programação em FORTRAN V. João Manuel R. S. Tavares

Linguagem de Programação I

Programação 2009/2010 MEEC - MEAer Laboratório 5 Semana de 26 de outubro de 2009

Transcrição:

Laboratório de Programação - Exercício 25 Funções de Argumentos Variáveis João Araujo Ribeiro jaraujo@uerj.br Universidade do Estado do Rio de Janeiro Departamento de Engenharia de Sistemas e Computação João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 1 / 19

Resumo 1 Ex25 - Funções de Argumentos Variáveis João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 2 / 19

Exercício 25 -Funções de Argumentos Variáveis Em C você pode criar suas próprias versões de funções como printf e scanf com uma função de argumento variável. Estas funções usam stdarg.h e com elas você pode criar belas interfaces para sua biblioteca. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 3 / 19

Necessárias? Entender funções vararg não é essencial para criar programas em C. Poucas vezes vocês precisará delas, contudo, saber como uma função vararg funciona vai te ajudar a debugar as que você usa e também você vai entender melhor como funciona o computador. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 4 / 19

ex25.c (1/6) 1 /** WARNING: Este código é recente e 2 ** pode ainda n~ao estar completamente correto. */ 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <stdarg.h> 6 #include "dbg.h" 7 8 #define MAX_DATA 100 9 10 int read_string(char **out_string, int max_buffer) 11 { 12 *out_string = calloc(1, max_buffer + 1); 13 check_mem(*out_string); 14 15 char *result = fgets(*out_string, max_buffer, stdin); 16 check(result!= NULL, "Erro na entrada."); 17 18 return 0; 19 20 error: 21 if(*out_string) free(*out_string); 22 *out_string = NULL; Continua João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 5 / 19

ex25.c (2/6) 23 return -1; 24 } 25 26 int read_int(int *out_int) 27 { 28 char *input = NULL; 29 int rc = read_string(&input, MAX_DATA); 30 check(rc == 0, "Falha na leitura de número."); 31 32 *out_int = atoi(input); 33 34 free(input); 35 return 0; 36 37 error: 38 if(input) free(input); 39 return -1; 40 } 41 42 int read_scan(const char *fmt,...) 43 { 44 int i = 0; João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 6 / 19

ex25.c (3/6) 45 int rc = 0; 46 int *out_int = NULL; 47 char *out_char = NULL; 48 char **out_string = NULL; 49 int max_buffer = 0; 50 51 va_list argp; 52 va_start(argp, fmt); 53 54 for(i = 0; fmt[i]!= \0 ; i++) { 55 if(fmt[i] == % ) { 56 i++; 57 switch(fmt[i]) { 58 case \0 : 59 sentinel("formato inválido, voc^e terminou com %%."); 60 break; 61 62 case d : 63 out_int = va_arg(argp, int *); 64 rc = read_int(out_int); 65 check(rc == 0, "Falha na leitura de int."); 66 break; João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 7 / 19

ex25.c (4/6) 67 68 case c : 69 out_char = va_arg(argp, char *); 70 *out_char = fgetc(stdin); 71 break; 72 73 case s : 74 max_buffer = va_arg(argp, int); 75 out_string = va_arg(argp, char **); 76 rc = read_string(out_string, max_buffer); 77 check(rc == 0, "Falha na leitura de string."); 78 break; 79 80 default: 81 sentinel("formato inválido."); 82 } 83 } else { 84 fgetc(stdin); 85 } 86 87 check(!feof(stdin) &&!ferror(stdin), "Erro na entrada."); 88 } João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 8 / 19

ex25.c (5/6) 89 90 va_end(argp); 91 return 0; 92 93 error: 94 va_end(argp); 95 return -1; 96 } 97 98 int main(int argc, char *argv[]) 99 { 00 char *prenome = NULL; 01 char inicial = ; 02 char *nome_de_familia = NULL; 03 int idade = 0; 04 05 printf("qual é seu prenome? "); 06 int rc = read_scan("%s", MAX_DATA, &prenome); 07 check(rc == 0, "Falha no prenome."); 08 09 printf("qual sua inicial do nome do meio? "); 10 rc = read_scan("%c\n", &inicial); João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 9 / 19

ex25.c (6/6) 11 check(rc == 0, "Falha em inicial."); 12 13 printf("qual é seu nome de família? "); 14 rc = read_scan("%s", MAX_DATA, &nome_de_familia); 15 check(rc == 0, "Falha no nome de fampilia."); 16 17 printf("qual sua idade? "); 18 rc = read_scan("%d", &idade); 19 20 printf("---- RESULTADOS ----\n"); 21 printf("prenome: %s", prenome); 22 printf("inicial: %c \n", inicial); 23 printf("nome de Família: %s", nome_de_familia); 24 printf("idade: %d\n", idade); 25 26 free(prenome); 27 free(nome_de_familia); 28 return 0; 29 error: 30 return -1; 31 } João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 10 / 19

read scan Este programa é similar ao exercício anterior, exceto que escrevemos uma versão própria de scanf que manipula strings ao nosso modo. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 11 / 19

Função varargs A função vararg aqui é chamada read scanf e faz a mesma coisa que scanf usando a estrutura de dados va list e suas funções e macros de suporte. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 12 / 19

Como funciona 1: Atribuímos ao último parâmetro da função a palavra-chave... que indica para C que esta função tomará qualquer número de parâmetros após o argumento fmt. Podemos colocar qualquer número de argumentos antes dele, mas não podemos colocar nenhum após. Após declarar algumas variáveis, criamos uma variável va list e a inicializamos com va start. Isto configura o mecanismo em stdarg.h que manipula os argumentos variáveis. Então usamos um loop for através da string de formatação fmt e processamos o mesmo tipo que scanf possui, porém muito mais simples. Temos apenas inteiros, caracteres e strings. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 13 / 19

Como funciona 2: Quando encontramos um formato, usamos um switch para saber o que fazer. Agora, para obter uma variável de va list argp usamos a macro va arg(argp, TIPO), onde TIPO é o tipo exato para o qual vamos atribuir este parâmetro. O problema deste design é que voamos às cegas, de forma que se você não tiver argumentos suficientes o programa vai dar crash. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 14 / 19

Como funciona 3: A diferença interessante para scanf é que assumimos que as pessoas querem read scan para criar strings que ela lê quando usa o formato s. Quando você fornece esta sequência, a função pega dois parâmetros da pilha de va list argp: o tamanho máximo para ler e o ponteiro da saáida da string de caracteres. Usando esta informação, apenas rodamos read string para fazer o trabalho correto. Isto faz read scan mais consistente que scanf, posto que você sempre fornece um endereço & nas variáveis para tê-las atribuídas corretamente. Finalmente, se encontramos um caractere que não está no formato, apenas lemos um caractere para saltá-lo. Não nos preocupamos sobre qual caractere é, apenas saltamos ele. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 15 / 19

Execução $ make ex25 cc -Wall -g -DNDEBUG ex25.c -o ex25./ex25 Qual é seu prenome? José Qual sua inicial do nome do meio? L Qual é seu nome de família? Silva Qual sua idade? 25 ---- RESULTADOS ---- Prenome: José Inicial: L Nome de Família: Silva Idade: 25 João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 16 / 19

Como quebrar o código? Este programa deve ser mais robusto contra buffer overflow, mas ele não trabalha com entrada formatada tão bem quanto scanf. Para tentar quebrá-lo, mude o código de modo a que você esqueça de passar o tamanho inicial para o formato %s. Tente também fornecer mais dados que MAX DATA, e então veja como não usar calloc em read string afeta como ela funciona. Finalmente, existe um problema que faz com que fgets coma o caractere de nova linha. Tente consertá-lo usando fgetc mas deixe o \0 que termina a string. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 17 / 19

Trabalho extra Tenha certeza absoluta sobre que acad uma das variáveis out estão fazendo.mais importante é out string e como ela aponta para um ponteiro, assim, entender quando você está atribuindo o ponteiro vs o conteúdo eé importante. Examine cada situação. Escreva uma função similar a printf que use o sistema varargs e reescreva o main para usá-la. Como sempre, leia a man page disto para entender como tudo funciona. Algumas plataformas usam macros e outras usam funções e algumas simplesmente nada. Tudo depende do compilador e da plataforma que você usa. João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 18 / 19

FIM João Araujo Ribeiro (UERJ) Laboratório de Programação LabProg 19 / 19