Universidade Federal de Minas Gerais Instituto de Ciências Exatas Departamento de Ciência de Computação DCC003 -- Algoritmos e Estruturas de Dados 1 -- 2013/1 -- Turma F Prática 9 -- Cálculo de raiz quadrada ############################################################################### INSTRUÇÕES: Salve suas soluções num arquivo .c (o nome está indicado entre parênteses no cabeçalho de cada exercício) e entregue no Moodle. IMPORTANTE: Coloque um comentário na primeira linha do arquivo contendo o(s) nome(s) do(s) aluno(s) que fizeram o código. (Um comentário em C é qualquer texto entre /* e */.) ############################################################################### DICAS: Para ler uma string de até 127 caracteres do teclado, use o seguinte código: char linha[128]; printf("digite uma linha:\n"); fgets(linha, 128, stdin); Para gerar um número aleatório em C entre 0 e RAND_MAX use a função rand() definida dentro de stdlib.h: #include /* no começo do arquivo */ int aleatorio = rand(); /* em qualquer ponto no programa */ Para alocar um vetor de X elementos do tipo Y use: Y * vetor = malloc(X * sizeof(Y)); /* Por exemplo: double * vetor = malloc(10 * sizeof(double)) */ /* Não esquecer de liberar a memória depois com free(vector)! */ Lembre-se que nomes de arranjos, quando usados sem colchetes, são convertidos em ponteiros. Além disso, temos que exp1[exp2] é semânticamente idêntico à *(exp1+exp2). Funções para manipulação de arquivos incluem: FILE * fopen(char *nome, char *modo); /* abrir um arquivo */ /* Use "r" para modo de leitura (read) e "w" para modo de escrita * (write). */ int fclose(FILE *arquivo); /* fechar um arquivo */ long ftell(FILE *arquivo); /* encontrar posição atual no arquivo */ int fseek(FILE *arquivo, long distancia, int base); /* mudar posição */ fprintf e fscanf, igual printf e fscanf mas aceitam arquivo como parâmetro. Exercício 1 -- SysBB (criaconta.c saque.c deposito.c defines.h) ############### Neste exercício iremos implementar uma versão simplificada do SysBB, o sistema do Banco do Brasil. Nossa versão simplificada terá programas para criar contas bem como realizar saques e depósitos. Todos os três programas devem ler e escrever um banco de dados compartilhado. Para facilitar, iremos implementar o banco de dados em um arquivo de texto, onde cada linha irá conter as informações de uma conta. O programa para criação de contas (criaconta.c) deve receber como parâmetro três informações: o número da conta a ser criada, o primeiro nome do titular (sem espaços para faciliar) e o saldo inicial da conta. Seu programa deve impedir a criação da conta se outra conta com o mesmo número já existir no banco de dados. Se os dados estiverem corretos, seu programa deve escrever as informações da nova conta na última linha do arquivo texto do bando de dados. Seu programa para realização de saques (saque.c) deve receber como parâmetro duas informações: o número da conta e o valor do sacado. Seu programa deve informar se o número da conta não existir e se o saldo da conta for insuficiente para realizar o saque. O programa de depósito (deposito.c) é similar ao programa de saque e recebe como parâmetro o número da conta e o valor depositado. Seu programa deve informar se a conta não existir. Para testar seu programa, crie várias contas, depois realize saques e depósitos em várias contas. Confira o formato do arquivo de texto com o banco de dados para garantir que ele está sendo modificado corretamente e não foi corrompido. Para simplificar, recomendamos: (i) exigir que o número das contas sejam inteiros positivos, (ii) proibir saldos negativos, (iii) assumir que os nomes são feitos apenas de letras minuscúlas sem acento, (iv) imprimir informações de uma conta por linha, (v) na ordem número da conta, nome do titular, saldo. Uma complicação da manipulação do arquivo do banco de dados é modificar o saldo de uma conta, pois ele fica no meio do arquivo. Para isso, precisamos abrir o arquivo do banco de dados para escrita e leitura [fopen(DATABASE, "rw+")]. Além disso, precisamos imprimir o saldo sempre com um número constante de caracteres para evitar sobrescrever outras informações no banco de dados. Tendo isso em mente, sugerimos que você coloque as as seguintes definições num arquivo chamado defines.h: #ifndef __DEFINES_H__ #define __DEFINES_H__ #define DATABASE "db.txt" #define DATABASE_LINE_LENGTH 1024 #define DB_AMOUNT_FORMAT "%015.2f" #define DB_AMOUNT_FSEEK (-15) #endif No programa para criar contas, imprima as informações da conta seguindo este esquema (adapte como necessário para seu programa, aqui é só a ideia): fprintf(db, "%d %s ", account_no, account_owner); fprintf(db, DB_AMOUNT_FORMAT, account_funds); fprintf(db, "\n"); Depois, nos programas de saque e depósito use o esquema abaixo para escrever o novo saldo (adapte como necessário para seu programa, aqui é só a ideia). (Observação: O código abaixo supõe que você acabou de ler a linha da conta onde o saque ou o depósito foi realizado e que o saldo é o último campo da linha. fseek(db, DB_AMOUNT_FSEEK-1, SEEK_CUR); /* -1 for \n */ fprintf(db, DB_AMOUNT_FORMAT, account_funds); fprintf(db, "\n"); Para começar o programa para criar contas, siga o esqueleto abaixo: #include #include #include #include "defines.h" int main(int argc, char **argv) { if(argc < 4) { /* mostrar ajuda e sair */ } /* abrir arquivo do banco de dados */ /* converter numero da conta, nome e saldo de argv para variaveis */ /* saia se o numero da conta ou nome forem invalido */ /* le todas as linhas do banco de dados pra ver se o numero * da conta sendo criada jah existe. se existir, avise e termine. */ /* escreva uma linha no final do arquivo texto do banco de dados com * a informação da nova conta */ exit(EXIT_SUCCESS); }