Professional Documents
Culture Documents
ndice 1. Introduo.................................................................................................................................. 2 2. Objectivo .................................................................................................................................... 3 2.1 Estrutura do trabalho...................................................................................................... 3 3. Hardware .................................................................................................................................... 4 3.1 Esquema da montagem ................................................................................................. 4 3.2 Descrio dos componentes ........................................................................................ 5 3.3 Explicao do circuito ................................................................................................. 15 4. Software .................................................................................................................................... 16 4.1 Algoritmo de aquisio e transmisso de dados pelo porto paralelo do PC 17 4.2 Simples base de dados ................................................................................................. 19 4.3 Interface com o utilizador ........................................................................................... 21 4.4 Ficheiros de inicializao............................................................................................ 23 4.5 Biblioteca de manipulao de strings................................................................. 26 5. Comentrios............................................................................................................................. 29 6. Apndice A............................................................................................................................... 31 6.1 Contedo do ficheiro irclone.cpp ......................................................................... 31 6.2 Contedo do ficheiro ir.h........................................................................................ 42 6.3 Contedo do ficheiro dui.h .................................................................................... 43 6.5 Contedo do ficheiro inifiles.h ............................................................................. 50 6.6 Contedo do ficheiro strlib.h................................................................................. 57 6.7 Contedo do ficheiro exception.h ........................................................................ 67 7. Apndice B............................................................................................................................... 68 7.1 Datashet do foto-diodo ................................................................................................ 68 7.2 Datashet do foto-transistor ......................................................................................... 75 7.3 Datashet do transstor NPN 3904............................................................................. 77 8. Bibliografia ............................................................................................................................... 84 9. Avaliao................................................................................................................................... 85 9.1 Identificao.................................................................................................................... 85 9.2 Observaes .................................................................................................................... 85 9.3 Classificao ................................................................................................................... 85 9.4 O docente ......................................................................................................................... 85
Pgina 2 de 85
Pgina 1 de 85
Pgina 3 de 85
Pgina 4 de 85
Foto-diodos
O foto-diodo um diodo de juno construdo de forma especial, de modo a possibilitar a utilizao da luz como factor determinante no controle da corrente elctrica. Pode ser aplicado no foco automtico de cmara de filmar, na unidade ptica do CD Player e em sistema contador de pulso. Num diodo comum polarizado reversamente, existe uma corrente reversa formada por portadores minoritrios mantidos pela energia trmica a temperatura ambiente. Assim, se houver incidncia de luz sobre a juno pn, essa energia tambm pode gerar portadores contribuindo para gerar corrente reversa. Portando, o foto-diodo possui uma abertura que permite a entrada de luz que produz electres livres e lacunas, aumentando a quantidade de portadores minoritrios, controlando assim, a corrente reversa. Dessa forma, quanto maior a incidncia de luz, maior a corrente no foto-diodo polarizado reversamente. Por isso, quando o foto-diodo est trabalhando na regio linear de sua curva caracterstica, a corrente reversa tem a mesma forma de onda da amplitude da intensidade luminosa incidente. Apesar do foto-diodo produzir, normalmente, corrente reversa por volta de dezenas de microampres, deve ser ligado em srie com uma resistncia limitador de corrente. Aplicaes: O foto-diodo usado como sensor em controlo remoto, em sistemas de fibra ptica, leitoras de cdigo de barras, scanner (digitalizador de imagens, para computador), canetas pticas (que permitem escrever na tela do computador), gira-discos CD, fotmetros e como sensor indirecto de posio e velocidade.
Diodo
Os diodos e as pontes rectificadores e os capacitores so elementos de uma importncia fundamental na electrnica. Iremos fazer agora um breve estudo destes dois elementos: Os diodos so componentes electrnicos formados por semicondutores. So usados como semicondutores, por exemplo, o silcio e o germnio, que em determinadas condies de polarizao, possibilitam a circulao de corrente.
Pgina 5 de 85
Pgina 6 de 85
Externamente, os diodos possuem dois terminais: nodo (A) e o Ctodo (K) e h, prximo ao terminal Ctodo uma faixa que o indica. Possui formato cilndrico. O diodo a aplicao mais simples da unio PN (semicondutores) e tem propriedades rectificadoras, ou seja, s deixa passar a corrente em um certo sentido (nodo-ctodo), sendo o contrrio impossvel, excepto nos diodos zener, que nessa condio deixam passar uma voltagem constante. Existem certas variaes na sua apresentao, de acordo com a corrente que o percorre. Existem tambm os diodos emissores de luz, os famosos LED's (light emissor diode), que so representados por um diodo normal mais duas pequenas flechas para fora, que indicam que emite luz. Possuem as mesmas propriedades dos diodos normais, porm, claro, emitem luz.
Clulas foto-voltaicas So dispositivos que convertem energia luminosa em elctrica. O diodo iluminado intensamente na juno pode reverter a barreira de potencial em fonte de electres, produzindo energia. A eficincia do processo baixa devido a pouca transparncia da juno (somente as camadas superficiais so iluminadas), apenas alguns %.
Caractersticas do foto-transstor;
O foto-transstor, como um transstor convencional, uma combinao de dois diodos de juno, no entanto, associa ao efeito transstor o efeito fotoelctrico. Em geral, possui apenas dois terminais acessveis (colector e emissor), no entanto, alguns incorporam o terminal de base para uma eventual polarizao ou controle elctrico. Seu funcionamento idntico ao do foto-diodo, excepto que o foto-transstor muito mais sensvel, devido aco amplificadora do efeito transstor. Se uma certa quantidade de radiao luminosa atinge a base, ocorre a gerao de portadores, aumentando corrente de base, o que implica numa variao da corrente de colector beta vezes maior e proporcional intensidade de luz incidente.
Foto-transstor
um transstor cuja juno colector-base fica exposta luz e actua como um fotodiodo. O transstor amplifica a corrente, e fornece alguns mA com alta luminosidade. Sua velocidade menor que a do foto-diodo. Suas aplicaes so as do foto-diodo, excepto sistemas de fibra-ptica, pela operao em alta-frequncia.
Pgina 7 de 85
Pgina 8 de 85
Pgina 9 de 85
Pgina 10 de 85
Escola Superior de Tecnologia Projecto Sistemas em Tempo Real Transstor 3904-tipo NPN
Os transstores so dispositivos que possuem duas unies PN (a mesma dos diodos), capazes de controlar a passagem de uma corrente. Podem ser de dois tipos, de acordo com as unies: PNP ou NPN. Apresentam base, emissor e coletor: A base a parte que controla a passagem de corrente; quando a base esta energizada, h passagem de corrente do emissor para o colector, quando no h sinal na base, no existe essa conduo. A base esquematicamente o centro do transstor. O colector uma das extremidades do transstor: nele que "entra" a corrente a ser controlada. A relao existente entre o colector e a base um parmetro ou propriedade do transstor conhecido como e diferente para cada modelo do mesmo. O emissor outra extremidade, por onde sai a corrente que foi controlada. Algumas caractersticas que devemos observar nos transstores so: A voltagem mxima entre base e colector, potncia mxima dissipvel (no caso do seu uso para controle de potncia) e frequncia mxima de trabalho. Os transstores podem ter aparncia externa completamente diferentes, dependendo da aplicao que se far dele, por exemplo, um transstor de sinal no possui a mesma aparncia externa de um transstor de potncia, que controle grandes cargas. Os seus terminais so os seguintes:
Pgina 11 de 85
Pgina 12 de 85
A ligao entre o circuito electrnico (controlo remoto) e o computador feita pela porta paralela do computador, atravs de um componente de 25 pinos, isto , a porta paralela consiste basicamente de trs partes: porta de dados, status e controle. Estas portas e seus respectivos endereos esto em ordem sequencial. Ento, se o endereo da porta de dados 0x378, ento sua porta correspondente de status 0x379 e de controle 0x37a.
Porta LPT1 LPT2 Porta Dados 0x0378 0x0278 Status 0x0379 0x0279 Controle 0x037a 0x027a
Para identificar o endereo das portas de um computador, use o debug do DOS para mostrar a localizao de memria 0040:0008. Por exemplo:
>debug -d 0040:0008 L8 0040:0008 78 03 78 02 00 00 00 00
Fig 1. Pinagem
Note neste exemplo que LPT1 0x0378, LPT2 0x0278 e LPT3 e LPT4 no esto disponveis. Um outro modo rodar o Microsoft Diagnostic (msd.exe) e verificar as configuraes da LPT.
Sadas Vejamos agora a sua pinagem figura 1 e a configurao das portas figura 2. As duas figuras seguintes ilustram a configurao dos pinos no conector de 25 pinos e as configuraes dos bits nas trs portas (dados, status e controle).
Observe que estas portas possuem 8 sadas na porta data (Data 7(msb) - Data 0) e quatro sadas adicionais no nibble inferior da porta controle (/SELECT_IN, INIT, /AUTO FEED and /STROBE). Todas as sadas da porta de dados so de lgica directa. Isto , colocando um bit desta porta em 1, sua sada correspondente vai ao nvel alto. Entretanto, as sadas /SELECT_IN, /AUTOFEED e /STROBE da porta controle possuem lgica invertida. Isto , colocando um destes em 1, sua sada correspondente vai ao nvel baixo. Isto pode parecer complicado, mas basta inverter estes bits atravs de software usando uma instruo XOR.
Pgina 13 de 85
Pgina 14 de 85
Este circuito um controlo remoto por radiao infravermelha onde pode ligar, desligar (ou fazer todas as outras funes) aparelhos distncia (operao biestvel) e utiliza poucos componentes de fcil obteno. A alimentao do circuito pode ser obtida atravs de uma fonte ou bateria e para maior alcance os foto-diodos podem ser dotados de um sistema ptico. Este sistema consiste num tubo de papelo opaco com lenta convergente na sua frente. A resistncia de 220 ohm na base do transstor fixa o ganho deste componente podendo ser alterado experimentalmente em funo da aplicao. Quanto ao receptor, onde podemos ver que um foto-transstor IRX que recebe o sinal do controlo remoto por radiao infravermelha e que o envia para o computador pela porta paralela atravs do pino 18.De seguida o sinal lido, gravado e tratado no computador atravs de um software tambm implementado por ns que ser descrito mais abaixo. Depois basta enviar esse mesmo sinal atravs da porta paralela do computador pelo pino 2 onde ser amplificado pelo transstor 3904 e emitido atravs dos dois foto-diodos (IRD1, IRD2) por radiao infravermelha para o respectivo aparelho fazendo a mesma funo que o controlo remoto faria. Com este circuito electrnico pondera-se receber e enviar enumeros sinais por radiao infravermelha de qualquer tipo de controlo remoto como por exemplo: de televisores, rdios, vdeos, etc.
Sendo C/C++ uma das linguagens de programao mais populares que se usa hoje em dia a escolha obvia. A linguagem C/C++ fornece um esqueleto estruturado, sem limitar a creatividade do programador, enquanto os compiladores dessa linguagem consistentemente produzem programas mais rpidos e eficientes. Por estas e outras razes, muitos pacotes de software so escritos integralmente em C/C++. Como existem mais programadores que conhecem C/C++ do que outras linguagens de programao actuais, tornou-se claro que para que o software tenha aplicabilidade no mundo real forosamente tm que ser escrito em C/C++. Enquanto outras linguagens, tal como Pascal, Basic ou Ada95 so boas para aprender conceitos relacionados com programao, a linguagem C/C++ sobresai porque uma linguagem de uso geral e em termos de portabilidade possvel escrever um software para Linux e compilado para correr em ambiente Windows sem alterar uma linha de cdigo. Decidido qual era a linguagem de programao a adoptar, era imperativo a escolha de um bom compilador. Na escolha do compilador foram ponderados varios factores, um dos factores mais significativos foi a compatibilidade dos formatos dos ficheiros, entre este compilalor e o compilador usado nas aulas prticas de Ada95 da cadeira de Sistemas em tempo real. (Caso mais tarde se deseja-se implementar o software em Ada95 bastaria simplesmente importar as rotinas de C/C++ para Ada95 sem muito esforo) O compilador utilizado foi um porto para MS-DOS do famoso Gcc ligado ao movimento Linux. Apesar deste compilador ser destribuido na internet livremente (incluindo cdigo fonte) no o faz de qualidade duvidosa, consta que o jogo Quake I tm que rendeu milhes Id Software foi desenvolvido nesse compilador o que vem a vincular que no existem maus compiladores, mas sim maus programadores. O compilador encontra-se disponivel para download no endereo de internet: http://www.delorie.com/djgpp/ Aps ter sido instalado, a linha de comandos para compilar o programa principal escrito em C/C++ a seguinte: No querendo utilizar o programa make que vem com a distribuio do compilador a linha de comando para compilar o programa principal a seguinte:
Pgina 15 de 85
Pgina 16 de 85
Deve-se salientar aqui que no se utilizou qualquer rotina de atraso, em vez disso preferiu-se aumentar o tamanho do buffer de dados caso assim seja necessrio. Para se poder obter melhores resultados na aquisio dos dados desligou-se momentneamente o atendimento de interrupes pelo processador. Assim tm-se a certeza que se consegue amostrar o sinal em intervalos de tempo mais regulares. O envio de um sinal a um aparelho receptor de infravermelhos tambm feito de modo expedito, em que o processo de amostragem invertido. Utilizando o mesmo buffer onde os bits que representam o sinal amostrado foram guardados, o software sequencialmente l um byte do buffer e envia-o para o porto paralelo, fazendo com que o bit mais significativo alinhe com o bit no porto de sada que controla o hardware. O seguinte pseudo-cdigo descreve o processo de envio: P = endereo_do_primeiro_byte_no_buffer_de_sada De contador = 1 at ao nmero_de_bytes_a_enviar faz Comea Vai buscar o byte apontado por P Incrementa ponteiro P Escreve no porto o byte Espera Acaba A implementao do pseudo-cdigo de envio em C o seguinte:
void irPlay(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j; unsigned char mask, d; // suspende as interrupes do processador _disable(); for (i = 0; i < length; i++) { mask = 128; d = buffer[i]; for (j = 0;j < 8; j++)
Pgina 17 de 85
Pgina 18 de 85
} // volta a inibir as interrupes do processador _enable(); // desliga a alimentao do fototransstor de emisso do sinal outp(baseport, 0); }
Se o envio do sinal for gerido com a mesma frequncia de amostragem, consegue uma boa reproduo do sinal infravermelho original.
Retirar os dados do ficheiro tambm pode ser feito de uma maneira expedita na maioria das linguagens de programao. Apesar deste tipo de armazenamento no ser muito aconselhvel para sistemas de bases de dados muito grandes e de ndole complexa, excelente para bases de dados mais pequenas e compactas. Tm a grande vantagem de no ser necessrio aprender a trabalhar com programas complexos para manipular a base de dados, um simples editor de texto ASCII serve para visionar e editar os dados (Isto pode comprometer a segurana em certos casos). Outra das formas de armazenar uma base de dados utilizando o sistema de ficheiros inerente ao sistema operativo. A maioria dos sistemas de ficheiros seguem atentamente o paradigma relacional em que um directrio representa uma tabela, o ficheiro representa uma linha na tabela, e os dados representam os atributos das colunas. Implementando uma base de dados baseada num sistema de ficheiros tambm muito expedito, e tm enumeras vantagens comparativamente implementao utilizando ficheiros de texto. Adicionar ou apagar um record no necessita de abrir o ficheiro e processa-lo tal como no mtodo utilizado anteriormente; em vez disso s necessrio editar apenas um ficheiro. Uma base de dados baseada no sistema de ficheiro Tambm fornece um melhor suporte no contexto de uma base de dados multiutilizador (est opo foi pouco explorada no mbito deste projecto). Com a implementao da base de dados, baseada num ficheiro ASCII, sempre que os utilizadores queiram modificar o ficheiro, o ficheiro deve ser bloqueado de modo a que os outros utilizadores fiquem impossibilitados de o fazer simultaneamente. Porque os records so entidades separadas na base de dados baseada no sistema de ficheiros, pode-se bloquear records individuais e mesmo assim deixar que os outros utilizadores modifiquem os outros records simultaneamente. Aps esta ligeira dissertao sobre mtodos de implementao do esquema de armazenamento dos sinais capturados em disco rgido. A soluo acordada foi um misto destas duas metodologias de armazenamento. Utilizou-se um ficheiro de inicializao para guardar as entradas no menu de transmisso, e para guardar os dados utilizaram-se ficheiros binrios. A metedologia adoptada na aquisio e armazenamento dos dados foi: Pedir ao utilizador um nome a atribuir ao sinal; Adquirir dados do porto paralelo utilizando o driver do hardware; Gerar aleatriamente um nome de um ficheiro; Abrir esse ficheiro para escrita e guardar nele os dados adquiridos; Adicionar ao ficheiro de inicializao (ficheiro com a extenso ini) a entrada no menu de transmisso e o nome do ficheiro onde est o sinal. Para mais informaes sobre os ficheiros de inicializao sugere-se a consulta da alnea 3.4 do presente documento. Pgina 20 de 85
Pgina 19 de 85
1. Consistncia. A coisa mais importante que se pode fazer ter a certeza que o interface com o utilizador funciona de uma forma consistente. Caso se clique numa lista e aconteceu algo, de esperar que ao clicar noutra lista idntica acontea o mesmo. 2. Definir padres e ser coerente com eles. A nica maneira que se consegue assegurar consistncia dentro de uma aplicao definir os padres de design e ser coerente com eles. 3. Explicar as regras. Os utilizadores precisam de saber como trabalhar com a aplicao que se construiu para eles. Quando uma aplicao funciona consistentemente significa que se s se deve explicar as regras uma vez. Isso mais fcil do que explicar detalhadamente como utilizar cada feio da aplicao passo a passo. 4. Suporte para principiantes e peritos. Tomando como analogia uma biblioteca onde existem causais utilizadores a consultar e um bibliotecrios, que so pessoas que tiveram formao a pesquisar mais eficientemente na base de dados. 5. A navegao entre os ecrs de informao importante. Se dificil ir de um ecr de informao para outro facilmente os utilizadores ficam frustrados e desistem. Quando a trasio entre ecrs coerente com o fluxo de trabalho que o utilizador est a tentar conseguir, ento a aplicao far sentido para os utilizadores. Porque varios utilizadores trabalham de maneiras diferentes preciso que o sistema seja flexivel nas suas enumeras abordagens. 6. A navegao dentro do ecr de informao importante. Nas sociedades ocidentais as pessoas lem da esquerda para a direita e de cima Pgina 21 de 85
para baixo. Deve-se organizar a navegao entre elementos no ecr de maneira que seja familiar ao utilizador. 7. Atribuir s mensagens ao utilizador palavras apropriadas. O texto que se mostra nos ecrs da aplicao a uma fonte primria de informao para os utilizadores. Se o texto tiver um lxico empobrecido ento o interface ser entendido pelos utilizadores de uma forma diminuta. Utilizando boas palavras e frases, opostamente a abreviaturas e cdigos faz com que o texto seja mais facil de entender. As mensagens devem ser entoadas positivamente, e dando opinies ao utilizador de como resolver o problema. Por exemplo, qual a mensagem que parece mais apeladora Vce inseriu a informao errada ou Por favor insira um inteiro entre 8 a 100 ? 8. Compreendes os elementos do interface com o utilizador. Deve-se utilizar o elemento de interface certo, ajudando a aumentar a consistncia na aplicao em desenvolvimento. 9. Usar as cores apropriadamente. A cor deve ser usada moderadamente nas aplicaes, e caso se use deve-se ter em mente um indicador secundrio. O problema prende-se com o facto de alguns utilizadores poderem vir a ser daltnicos, se se utilizar uma cor para sobresair algo no ecr talvez seja necessrio transmitir informao redundante (colocar um cone ao p do texto por exemplo). Tambm se deve ter em mente que algumas aplicaes no conseguem traduzir fielmente as intenes dos programadores em diferentes sistemas. 10. Seguir a regra de contraste. Caso se utilize cor nas aplicaes deve-se assegurar que os ecrs de informao podem ser lidos pelos utilizadores. 11. Fazer um bom uso de tipos de letras. Entenda-se que alguns tipos de letra ficam bem em livros mas no ecr so dificeis de ler. 12. Agrupar coisas efectivamente nos ecrs de informao. Items que esto logicamente relacionados devem ser agrupados juntos no ecr para comunicar ao utilizador que eles esto ligados, contrariamente items que no tm nada a ver uns com os outros devem ser separados.
Pgina 22 de 85
entrada1 = valor1 entrada2 = valor2 : : Os comentrios comeam sempre com o caracter ;, as seces do ficheiro so delimitadas por [ e ] e as entradas nas seces so separadas dos valores pelo caracter =. Como se pode ver um formato muito simples, tendo uma grande vantagem de poderem ser editados manualmente com a ajuda de um editor de texto ASCII, tal como o notepad do Windows 9X. A classe em C++ capaz de lidar com este tipo de ficheiro a seguinte:
class Figura 1 Menu principal do programa de captura de dados inifile { public: inifile(const string&); ~inifile(); const string& readstring(const string&, const string&, const string&); void writestring(const string&, const string&, const string&); long readlong(const string&, const string& , const long); void writelong(const string&, const string&, const long); void removesection(const string&); void removekey(const string&, const string&); void readsection(const string&,stringlist&); private: string filename; int altered; class inisection { public: string name; class inientry { public: string key; string value; inientry(); inientry(const string&, const string&); ~inientry(); void add(const string&, const string&); void remove(const string&); inientry* find(const string&); friend class inifile; armadura armadura // cuidado, buraco na
Na figura ilustra-se o ecr principal do programa que nos permite capturar sinais infravermelhos atravs de um PC. As rotinas que nos permitiram criar um interface com o utilizador esto contidas no ficheiro dui.h, algumas rotinas foram inspiradas pelos sistemas operativos grficos que proliferam nos computadores pessoais. Com o uso de um sistema de menus, o programa tornou-se simples de usar.
friend class inisection; // cuidado, buraco na private: inientry *next; } entries; inisection(const string); inisection(); ~inisection(); void add(const string &); void remove(const string&);
Pgina 24 de 85
Esta classe tomou partido da biblioteca de strings que nos permite manipular strings de uma forma transparente. Como no do mbito deste projecto, explicar exaustivamente o que cada palavra de cdigo faz concretamente vamos sim virar as nossas atenes para a parte do interface da classe (a seco debaixo do palavra chave public). O interface com o mundo externo da classe faz-se atravs de um constructor (inifile(const string&))que inicializa a classe, recebendo como parmetro o nome do ficheiro que de seguida abre e carrega para a memria do sistema. Andando uma linha ou duas na seco pblica da classe encontra-se o destructor que faz o efeito oposto do constructor, isto guarda os dados em memria num ficheiro em disco. Uma linha mais abaixo encontra-se os mtodos que nos permitem lr e escrever dados no ficheiro:
const void long void void string& readstring(const string&, const string&, const string&); writestring(const string&, const string&, const string&); readlong(const string&, const string& , const long); writelong(const string&, const string&, const long); readsection(const string&,stringlist&);
Uma das coisas que qualquer programador de Pascal/Delphi sente falta quando contacta pela primeira vez com a linguagem de programao C, o facto de no se poder manipular facilmente strings. Para executar operaes com strings preciso incluir um cabealho que disponibiliza funes idealizadas para a manipulao de strings. Uma das vantagens de C++ em relao a C o facto de permitir um mecnismo denominado operator overloading, isto , por exemplo redefinir o operador + de modo que a instruco S1 = S2 + S3; Permita concatenar duas strings. A definio da classe string a seguinte:
class string { private: char* _str; long _size; string& hex(char); public: string(); string(char*); string(const string&); ~string(); int length() const; // tamanho da string void urlencode(); void urldecode(); string& slice(int,int); string& operator= (const string&); string& operator= (const char*); string& operator+=(const string&); string& operator+=(const char*); char operator[](int) const; char& operator[](int); const char* c_str() const { return _str; } // buracos na armadura, possiveis fontes de "bugs" friend ostream& operator<<(ostream&,const string&); friend istream& operator>>(istream&,string&); friend string& operator+ (const string&, const string&); friend int operator==(const string&, const string&); friend int operator!=(const string&, const string&); friend int operator> (const string&, const string&); friend int operator< (const string&, const string&); friend class stringlist; };
Os nomes por si s so sugestivos em que os identificadores associados a long permitem ler valores inteiros e os nomes associados palavra string permitem lr ou escrever cadeias de caractres. Salienta-se que o uso especial do mtodo readsection que serve para lr as entradas todas debaixo de uma seco.
void void removesection(const string&); removekey(const string&, const string&);
Por fim os mtodos que nos permitem apagar entradas no ficheiro. O primeiro mtodo permite remover uma seco inteira e o outro s uma nica entrada.
Pgina 25 de 85
Pgina 26 de 85
Est instruo em C, no tm qualquer significado visto que a traduo que o compilador faria era comparar endereos de memria e no o contedo. Com o uso do operator overloading pode-se dizer ao compilador para tratar de um modo diferente as expresses que encontra. Nisto que se acabou de se ver, est a flexibilidade da lngua C++. Apesar de Ada95 possuir o mesmo mecnismo existe muitos casos em que se torna impraticavel a implementao em Ada95, visto que uma linguagem que visa agradar o leitor do cdigo fonte e no o programador. Como C++ no tm esse intuito, uma linguagem mais virada para o programador consegue reduzir o tempo de desenvolvimento para metade, desde que se saiba o que se est a fazer. Apesar de correr o boato que C++ uma lingua complexa e que s algumas pessoas podem dominar isso mentira, pense-se nos caractres chineses primeira vista pode parecer criptico mas quando se conhece a gramtica e se sabe o que significa cada smbolo, as coisas mudam de figura, o que desmotivamente por vezes a evoluo lenta na apreenso de novos conceitos. Mas adiante, aps ter-se criado uma classe que facilita a manipulao de strings quase institivamente se pensa em criar uma classe que trate de vrias strings. Esse objectivo materializou-se na forma da classe stringlist que est assim definida:
class stringlist { private: string **table; int lines; public: stringlist(); stringlist(const char*); stringlist(const string&); stringlist(const stringlist&); stringlist(const char**, const int argc = 0); ~stringlist(); void clear(); void add(const string&); void add(const char*); void add(const stringlist&);
};
A funcionalidade desta classe foi inspirada na linguagem interpretada PERL muito popular no mundo Linux. Com esta classe pode-se fazer tudo o que possvel e imaginrio com strings sendo por isso, usada intensivamente em quase todas as linhas de cdigo que constituem o software de captura de sinais infravermelhos.
Pgina 27 de 85
Pgina 28 de 85
A razo para a qual se utiliza este esquema de transmisso que deste modo pode-se utilizar um filtro sintonizado frequncia portadora e recuperar o sinal distinguindo assim o sinal do rudo proveniente da luz ambiente. Como que os botes pressionados no controlo remoto so codificados? No caso da norma RC5 existe um standard internacional, em que cada comando codificado por 14 bits. Os primeiros dois bits S so startbits para permitirem a sincronia entre o emissor e receptor do sinal. A seguir segue-se o bit T, que se liga cada vez que um boto pressionado. A seguir vem o endereo A do dispositivo que dever responder ao comando. Finalmente segue-se o comando em si.
| S | S | T | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |
Alguns endereos e comandos importantes: Note-se que o 1 demora mais tempo a transmitir que o 0. O cdigo RC5 em vez de adoptar este mtodo de transmisso de dados usa uma durao uniforme para codificar ambos os bits. A transio a meio do intervalo de tempo atribuido a cada bit codifica o sianl. Um 0 codificado por transio de alto para baixo e o 1 por uma transio de baixo para alto. Contudo so necessrias transies adicionais no ncio de cada bit para se descodificar eficientemente o sinal uma srie de bits iguais. Por isso que em algumas numenclaturas dado a este tipo de codificao bifsica. Endereo 0 1 6 17 18 20 6 7 8 9 Dispositivo TV1 TV2 VCR1 VCR2 Tuner Audio Tape CD Player Comando 0..9 (seleo de canais) 12 (standby) 16 (incremento do volume) 17 (decremento de volume) 18 (incremento da luminosidade) 19 (decremento da luminosidade) 50 (fast rewind) 52 (fast run forward) 53 play 54 stop 55 recording
Em vez de se enviar este sinal directamente para o emissor de infravermelhos, a maioria dos controlos remotos modulam os dados com uma frequncia portadora que ronda 20 a 30kHz. Um 1 lgico representado como sendo um trem de oscilaes.
Pgina 29 de 85
Pgina 30 de 85
lptport = ini.readlong("options","lptport",1111); if(lptport == 1111) { // erro a entrada no ini no existe lptport = defaultLPTport; } if(ini.readstring("options","mode","error") == "continuous") continuous = 1; else continuous = defaultMode; // erro a entrada no existe bufsize = ini.readlong("options","bufsize",1111); if(bufsize == 1111) // a entrada no existe bufsize = defaultBufsize; wipescr(); do { _setcursortype(_NOCURSOR); background("PCircloner v1.0",MENU_KEYS); switch((option=menu(items,7))) { case 1: wipescr(); sendsignal(); case 2: wipescr(); capturesignal(); case 3: wipescr(); surgery(); case 4: wipescr(); showoptions(); case 5: wipescr(); showhelp(); case 6: wipescr(); showcredit(); case 7: option = 0; break; } }while(option); wipescr(); cout << "PCircloner v1.0 "<< __DATE__ << endl;
//#define DEBUG hardware #include #include #include #include #define #define #define #define
"strlib.h" // biblioteca de manipulao de "strings" "inifiles.h" // ficheiros ini "dui.h" // dos user interface "ir.h" // driver do hardware INIFILENAME "irclone.ini" defaultLPTport 888 // transmisso do sinal por impulsos defaultMode 0 defaultBufsize 30*1024 // um buffer 30k, mais do que suficiente
int lptport ; // porto da impressora int continuous; // transmisso continua do sinal int bufsize ; // tamanho do buffer // prottipos das funes utilizadas no programa void void void void void void sendsignal(); capturesignal(); surgery(); showcredit(); showoptions(); showhelp(); // ficheiro ini onde se guarda toda a informao
// actualiza o ficheiro ini referente s opes if(continuous) ini.writestring("options","mode","continuous"); else ini.writestring("options","mode","burst"); ini.writelong("options","lptport",lptport); ini.writelong("options","bufsize",bufsize); } catch(exception &e) { textbackground(BLACK); clrscr(); cout << "\n DEBUG(" << e.code << "):" << e.msg << endl; cout << " " << e.src <<endl;
Pgina 31 de 85
Pgina 32 de 85
entrada"); gotoxy(14,12); newname = inputstr(PTFILTER,45); a funo foi cancelada if(newname.length() == 0) break; // string vazia
value = ini.readstring("signals",oldname,"ERROR"); // impossivel falhar ini.removekey("signals",oldname); ini.writestring("signals",newname,value); textbackground(BLACK); window(1,5,80,21); clrscr(); window(1,1,80,25); // volta a restaurar o tamanho da janela case 2: break; ini.readsection("signals",entries); if(entries.count() == 0) { messagebox("No existe nenhum sinal break; } item = listbox(entries,13,6,51,12); if(!item) break; // foi cancelado textbackground(BLACK); window(1,5,80,21); clrscr(); window(1,1,80,25); // volta a restaurar o tamanho da janela ini.removekey("signals",entries[item-1]); break; case 3: ini.readsection("signals",entries); if(entries.count() == 0) { messagebox(" No existe nenhum sinal break; } for(int i=0 ;i < entries.count(); i++) { ini.removekey("signals",entries[i]); }
capturado");
deseja alterar");
item = listbox(entries,13,6,51,12); menu principal if(!item) break; // foi cancelado volta para o textbackground(BLACK); window(1,5,80,21); // limpa o ecr na janela especificada da janela textcolor(WHITE); gotoxy(13,8); clrscr(); window(1,1,80,25); // volta a restaurar o tamanho
capturado");
Pgina 33 de 85
Pgina 34 de 85
bin rio");
if(!fread(buffer,buflen,1,handle)) { fclose(handle); delete []buffer; messagebox("Erro de leitura do ficheiro return; } if(continuous) { gettext(1,1,80,25,screen); textbackground(BLUE); window(20,10,60,15); clrscr(); window(1,1,80,25); textcolor(YELLOW); frame(20,10,60,15); // desenha um "frame" textcolor(WHITE); gotoxy(23,12); delaywrite("Modo de transmisso contnuo
void sendsignal() { _setcursortype(_NOCURSOR); background("Transmitir sinal",MENU_KEYS); int option; char screen[4096]; char* buffer; long buflen; string filename; FILE* handle; // saca do ini os valores das seces stringlist list; ini.readsection("signals",list); if(!list.count()) { messagebox(" No existe nenhum sinal capturado"); return; } do { option = listbox(list,13,6,51,12); if(option) { filename = ini.readstring("signals",list[option1],"error"); if(filename == "error") { messagebox("Erro a ler o ficheiro ini"); return; } handle = fopen(filename.c_str(),"rb"); if(!handle) { messagebox("Erro a ler o ficheiro bin rio"); return; } // calcula o tamanho do ficheiro fseek(handle,0L,SEEK_END); buflen = ftell(handle); fseek(handle,0L,SEEK_SET); buffer = new char[buflen]; if(!buffer) { fclose(handle); messagebox("Erro falta de memria");
activo"); gotoxy(26,13); delaywrite("Pressione <ESC> para terminar"); do { #ifndef DEBUG irPlay(buffer,buflen,lptport); #endif }while(getch() != ESC_KEY); puttext(1,1,80,25,screen); } else #ifndef DEBUG irPlay(buffer,buflen,lptport); #endif
} } while(option); }
_setcursortype(_NORMALCURSOR); void showhelp() { #define MAX_ITEMS 11 char* help[MAX_ITEMS] = { "O software, no faz qualquer deteco de hardware ", "caso no exista nenhuma placa de aquisio dos ", "dados pelo porto paralelo, o programa bloqueia.", "Escolheu-se esta soluo para no aumentar o nmero ", "de componentes electrnicos necess rios ao projecto.", "",
Pgina 35 de 85
Pgina 36 de 85
Pressione <ESC> para continuar int key,i; int index = 0; struct point{ int x; int y; } points[3] = {{49,11},{49,13},{49,15}}; int ports[2] = {888,0x238}; int bufsizes[8]= {8*1024,16*1024,32*1024,64*1024,128*1024,256*1024,512*1024,1024*1024}; int portindex = 0; int bfindex = 0; _setcursortype(_NOCURSOR); background("Opes",MENU_KEYS); textbackground(BLACK); textcolor(WHITE); highvideo(); frame(18,7,62,19); textcolor(GREEN); gotoxy(22,11); cprintf("Endereo base do porto : [ gotoxy(22,13); cprintf("Tamanho do buffer : [ gotoxy(22,15); cprintf("Modo de transmisso : [
Pgina 37 de 85
Pgina 38 de 85
do { textcolor(WHITE); lowvideo(); for(i=0;i<3;i++) { switch(i) { case 0: gotoxy(points[i].x,points[i].y); cprintf("%7xh",lptport); break; case 1: gotoxy(points[i].x,points[i].y); cprintf("%8i",bufsize); break; gotoxy(points[i].x,points[i].y); if(continuous) cprintf("contnuo"); else cprintf("impulso "); break; } } highvideo(); switch(index) { }
} break;
} if(index < 0) index = 0; if(index >=3) index = 2; }while(key != ESC_KEY); _setcursortype(_NORMALCURSOR); string& randfilename() { const string letters("abcdefghijklmnopqrstuvwxyz012345678_$"); static string res; char dummy[2] = {'?','\0'}; time_t t; srand((unsigned)time(&t)); // inicia gerador de nmeros aleatrios res=""; for(int i=0;i<8;i++) { dummy[0] = letters[rand() % letters.length()]; res +=dummy; } res = "./signals/"+res+".ir"; // extenso do ficheiro return res;
case 2:
case 0: gotoxy(points[index].x,points[index].y); cprintf("%7xh",lptport); break; gotoxy(points[index].x,points[index].y); cprintf("%8i",bufsize); break; case 2: gotoxy(points[index].x,points[index].y); if(continuous) cprintf("contnuo"); else cprintf("impulso "); break;
case 1:
void capturesignal() { _setcursortype(_NOCURSOR); string filename(randfilename()); // cria aleatriamente FILE* handle; // handle para um // buffer para os char* buffer; unsigned int length; // comprimento do background("Adquirir sinal",""); textcolor(WHITE); textbackground(BLACK); gotoxy(16,8); highvideo(); textcolor(WHITE); delaywrite("Nome a atribuir ao sinal"); string entry; _setcursortype(_NORMALCURSOR); textcolor(WHITE); gotoxy(16,9); cprintf("["); gotoxy(16+48,9); cprintf("]"); frame(14,7,14+52,7+3); // nome do sinal gotoxy(18,9);
} key = getch(); switch(key) { case UPARROW_KEY : index--; break; case DOWNARROW_KEY : index++; break; case ENTER_KEY: switch(index) { case 0 : lptport = ports[portindex & 0x1]; portindex++; break; case 1 : bufsize=bufsizes[bfindex & 0x7]; bfindex++; break;
// mostra cursor
Pgina 39 de 85
Pgina 40 de 85
// Implementao unsigned int irRecord(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j, len; unsigned char mask, d; // desliga momentaneamente as interrupes do processador _disable(); // liga a alimentao do fotododo outp(baseport,2); // espera at que exista sinal no porto while ((inp(baseport+1) & 16) == 0); while ((inp(baseport+1) & 16) == 16); for (i = 0; i < length; i++) { mask = 128; d = 0; for (j = 0; j < 8; j++){ if ((inp(baseport+1) & 16) == 0) d |= mask; mask = mask >> 1; } buffer[i] = d;
Pgina 41 de 85
Pgina 42 de 85
/* Interface */ #define MENU_KEYS <\x19> " #define PTFILTER #define #define #define #define #define #define #define " cancelar <ESC> aceitar <\xC0\x10> escolher <\x18> ,
"abcdefgqhijklmnopqrstuvwxyz0123456789 " 13 27 72 80 73 81 8
void irPlay(char* buffer, unsigned int length, unsigned int baseport) { unsigned int i, j; unsigned char mask, d; // suspende as interrupes do processador _disable(); for (i = 0; i < length; i++) { mask = 128; d = buffer[i]; for (j = 0;j < 8; j++) { if (d & mask) outp(baseport,1); else outp(baseport,0); mask = mask >> 1; } // volta a inibir as interrupes do processador _enable(); // desliga a alimentao do fototransstor de emisso do sinal outp(baseport, 0); } #endif }
void background(const string& title,const string& keys); int menu(char* items[],int MAX_ITEMS); void wipescr(); void frame(int x1, int y1, int x2, int y2); void hscrollbar(int x, int y, int size,int pos, int max); int listbox(stringlist list, int x, int y, int sizeX, int sizeY); void delaywrite(const string &s); void pause(); void vsync(); string& inputstr(const string& filter, int size); void messagebox(const string& str); /* Implementao */ static void hline(int y, int x1, int x2) { for(int i=x1;i<x2;i++) { gotoxy(i,y); cprintf("%c",205); } } //pseudo funo #define putchxy(x,y,ch) gotoxy(x,y); cprintf("%c",ch)
void frame(int x1, int y1, int x2, int y2) { int i; putchxy(x1,y1,218); putchxy(x2,y1,191); putchxy(x1,y2,192); putchxy(x2,y2,217); for(i = x1 + 1; i < x2;i++){
Pgina 43 de 85
Pgina 44 de 85
void background(const string& title,const string& keys) { textbackground(BLACK); clrscr(); highvideo(); textcolor(GREEN); hline(4,1,80-12); hline(22,12,80); textcolor(WHITE); lowvideo(); gotoxy(13,23); cprintf(" Copyright (c) 2002 N. Loureiro, H. Cardoso & F. Belo"); gotoxy(80-12-title.length()-6,3); cprintf("%s",title.c_str()); textbackground(BLUE); textcolor(WHITE); gotoxy(13,21); cprintf("%s",keys.c_str()); } int menu(char* items[],int MAX_ITEMS) { int index = 1; int key; int i; int centerX = 40 - strlen(items[0])/2; _setcursortype(_NOCURSOR); textbackground(BLACK); textcolor(WHITE); frame(centerX-1,9,centerX+strlen(items[0]),9+MAX_ITEMS+1); do { for (i=0;i<MAX_ITEMS;i++) { lowvideo(); textcolor(WHITE); textbackground(BLACK); gotoxy(centerX,10+i); cprintf(items[i]); } highvideo(); textcolor(WHITE); textbackground(GREEN); gotoxy(centerX,10+index-1); cprintf(items[index-1]); key = getch();
void hscrollbar(int x, int y, int size,int pos, int max) { char* sep = "\xC3\xC4\xB4"; int i; if(size <= 0) size = 1; if(max <= 0) max = 1; frame(x,y,x+2,y+size+6); gotoxy(x,y+2); cprintf(sep); gotoxy(x,y+size+6-2); cprintf(sep); gotoxy(x+1,y+1); cprintf("\x1E"); gotoxy(x+1,y+size+6-1); cprintf("\x1F"); for(i= y+3 ;i <= y+size+3;i++) { gotoxy(x+1,i); cprintf(" "); } float location; if(pos > max) location = size; else location = ((float) pos / (float)max)* (float) size; gotoxy(x+1,y+3+(int)location); cprintf("\xDB"); gotoxy(x+1,y+1); if((int)location == size) textcolor(GREEN); cprintf("\x1E"); textcolor(WHITE); if(((int)location != size) && ((int) location != max)) textcolor(GREEN);
Pgina 45 de 85
Pgina 46 de 85
: : : :
if(index < 0) index = 0; if(index >= list.count()) index = list.count()-1; } while((key != ESC_KEY) && (key != ENTER_KEY)); _setcursortype(_NORMALCURSOR); if(key == ESC_KEY) { // foi cancelado return 0; } else // devolve o ndice da "string" seleccionada return index+1; } void delaywrite(const string &s) { int tm = 1200 / (s.length()+1); int x1,y1; int i; x1 = wherex(); y1 = wherey(); for (i=0;i < s.length();i++) { delay(tm); cprintf("%c",s[i]); if(kbhit()) break; } gotoxy(x1,y1); cprintf("%s",s.c_str()); } void pause() { do {} while(getch() != ESC_KEY); } static int checkfilter(const string& filter,char ch) { for(int i=0;i<filter.length();i++) // o caracter existe no filtro if(filter[i] == tolower(ch)) return 1; // o caracter no existe no filtro return 0;
Pgina 47 de 85
Pgina 48 de 85
if(res.length() > size) { // simula a tecla enter key = ENTER_KEY; break; // sai do loop } if((key == ENTER_KEY) && (!res.length())) // nada de "strings" vazias key = 'x'; } while((key != ESC_KEY) && (key != ENTER_KEY));
Pgina 49 de 85
Pgina 50 de 85
#define TMPINI "tempini.$$$" // nome do ficheiro ini temporrio class ifexception : public exception { public: ifexception(int _code, char* _src, char* _msg) { code = _code; src = _src; msg = _msg; } virtual ~ifexception() {} }; class inifile { public: inifile(const string&); ~inifile(); const string& readstring(const string&, const string&, const string&); void writestring(const string&, const string&, const string&); long readlong(const string&, const string& , const long); void writelong(const string&, const string&, const long); void removesection(const string&); void removekey(const string&, const string&); void readsection(const string&,stringlist&); private: string filename; int altered; class inisection { public: string name; class inientry { public: string key; string value; inientry(); inientry(const string&, const string&); ~inientry(); void add(const string&, const string&); void remove(const string&); inientry* find(const string&); friend class inifile; armadura armadura // cuidado, buraco na
friend class inisection; // cuidado, buraco na private: inientry *next; } entries; inisection(const string); inisection(); ~inisection(); void add(const string &); void remove(const string&); inisection* find(const string&); friend class inifile;
Pgina 51 de 85
Pgina 52 de 85
while(section) { out << "[" << section->name << "]\n" << endl; entry = section->entries.next; _assert(out.fail(),ifexception(4,"inifile::~inifile()","erro de escrita no ficheiro")); while(entry) { out << entry->key << "=" << entry->value << endl; _assert(out.fail(),ifexception(4,"inifile::~inifile()","erro de escrita no ficheiro")); } entry = entry->next;
out << endl; // muda de linha, no necessrio mas melhora o aspecto do ficheiro section = section->next; } out.close(); // liberta o handle do ficheiro // apaga o ficheiro do disco remove(filename.c_str()); rename(TMPINI,filename.c_str());// muda de nome ao ficheiro temporrio } } void inifile::removekey(const string& section, const string& key) { inisection* ref = sections.find(section); if(ref) ref->entries.remove(key); inifile::removesection(const string& section) { sections.remove(section);
} void } void inifile::readsection(const string& section, stringlist& list) { inisection* ref = sections.find(section); inisection::inientry * entry; list.clear(); if(ref) { entry = ref->entries.next; while(entry) { //cout << entry->key << endl; list.add(entry->key); // adiciona os elementos lista entry = entry->next; } }
inifile::inisection::inisection(const string nm) { next = NULL; name = nm; } inifile::inisection::inisection() { next = NULL; name = ""; }
Pgina 53 de 85
Pgina 54 de 85
inifile::inisection::~inisection() { delete next; // apaga recursivamente os outros nodos } void inifile::inisection::remove(const string& _name) { inisection* ptr = this; inisection* prior= this; while((ptr = ptr->next)) { if(ptr->name == _name) { prior->next = ptr->next; ptr->next = NULL; delete ptr; return; } prior = ptr; ptr = ptr->next; } } void inifile::inisection::add(const string& _name) { if(find(_name)) return; // o nome da secco j existe aborta if(next) { inisection* ptr = this; while(ptr->next) ptr = ptr->next; ptr->next = new inisection(_name); _assert(!ptr->next,ifexception(1,"void inifile::inisection::add(const string& _name)","falta de memria")); } else {
next = new inisection(_name); _assert(!next,ifexception(1,"void inifile::inisection::add(const string& _name)","falta de memria")); } } inifile::inisection* inifile::inisection::find(const string& _name) { inisection* ptr = next; while(ptr) { if(ptr->name == _name) return ptr; ptr = ptr->next; } return NULL; } inifile::inisection::inientry::inientry() { next = NULL; key = ""; value= ""; }
void inifile::inisection::inientry::add(const string& _key, const string& _value) { inientry* entry = find(_key); if(entry) { // a entrada j existe actualiza entry->value = _value; return; } if(next) { inientry* ptr = next; while(ptr->next) ptr = ptr->next; ptr->next = new inientry(_key,_value); _assert(!ptr->next,ifexception(1,"void inifile::inisection::inientry::add(const string& _key, const string& _value)","falta de memria")); } else { next = new inientry(_key,_value);
Pgina 55 de 85
Pgina 56 de 85
strexception: public exception { public: strexception(int c, char* s, char* m) { code=c; src = s; msg=m; } virtual ~strexception() {} };
// prottipo da class class stringlist; class string { private: char* _str; long _size; string& hex(char); public: string(); string(char*); string(const string&); ~string(); int length() const; // tamanho da string void urlencode(); void urldecode(); string& slice(int,int); string& operator= (const string&); string& operator= (const char*); string& operator+=(const string&); string& operator+=(const char*); char operator[](int) const;
Pgina 57 de 85
Pgina 58 de 85
string::string(char* s) { _str = new char [strlen(s)+1]; _assert(!_str,strexception(1,"string::string(char* s)","falta de memria")); strcpy(_str,s); _size = strlen(_str); } string& string::slice(int start, int end) { int tmp; if(start > end) { // permuta valores tmp = start; start = end; end = tmp; } _assert((start < 0) || (start >= _size) || (end < 0) || (end >= _size), strexception(2,"string& string::slice(int start, int end) {","ndice fora de limites")); _str[end+1] = '\0'; strcpy(_str,_str+start); _size = strlen(_str); return *this; } string::string(const string& s) { _str = new char [strlen(s._str)+1]; _assert(!_str,strexception(1,"string::string(const string& s)","falta de memria")); strcpy(_str,s._str); _size = strlen(_str); } string::~string() { delete []_str; } int string::length() const{ return _size; } string& string::operator=(const string& s){ if(this != &s) { delete []_str; _str = new char[strlen(s._str)+1]; _assert(!_str,strexception(1,"string& string::operator=(const string& s)","falta de memria")); strcpy(_str,s._str); _size = strlen(_str); } return *this; }
_assert((pos < 0) || (pos > _size),strexception(2,"char string::operator[](int pos) const","ndice fora dos limites")); return _str[pos]; } char& string::operator[](int pos) { _assert((pos < 0) || (pos > _size),strexception(2,"char& string::operator[](int pos)","ndice fora dos limites")); return _str[pos]; } string& string::hex(char ch) { const char hextable[] = "0123456789ABCDEF"; static string tmp; char dummy[2]; dummy[1] = 0; dummy[0] = hextable[ch & 0x0F]; tmp = dummy; dummy[0] = hextable[(ch >> 4) & 0x0F]; tmp = dummy + tmp; return tmp; } void string::urlencode() { const char* ptr = _str; char dummy[2] = {' ','\0'};
Pgina 59 de 85
Pgina 60 de 85
operator!=(const string& s1, const string& s2) { return strcmp(s1._str, s2._str); operator>(const string& s1, const string& s2) { return strcmp(s1._str, s2._str) > 0; operator<(const string& s1, const string& s2) { return strcmp(s1._str, s2._str) < 0;
ostream& operator<<(ostream &out, const string& s) { out << s._str; return out; } istream& operator>>(istream &in, string& s) { char buf[2] = {' ','\0'}; int ch; s = ""; while ((ch = in.get()) != EOF) { _assert(ch == '\0',strexception(5,"istream& operator>>(istream &in, string& s)","ficheiro bin rio")); if(ch != '\n') { buf[0] = ch; s += buf; } else break; // a "string" acaba com um '\n' } in.putback(ch); return in; } string& operator+(const string& s1, const string& s2) { static string tmp; tmp = s1; tmp +=s2; return tmp; } int } operator==(const string& s1, const string& s2) { return !strcmp(s1._str,s2._str);
stringlist::stringlist(const char** s,const int argc) { table = NULL; lines = 0; if(argc == 0) { for (int i=0; s[i]; i++) { add(s[i]); } } else for (int i=0; i < argc; i++) add(s[i]); } stringlist::~stringlist() { clear(); } void stringlist::clear() { for(int i=0;i<lines;i++) { delete table[i]; // liberta a memria dos ponteiros } delete []table; lines = 0; stringlist::count() const { return lines;
} int }
string& stringlist::operator[](int pos) { _assert((pos < 0) || (pos >= lines),strexception(2,"string& stringlist::operator[](int pos)","ndice fora dos limites")); return *table[pos]; } const string& stringlist::operator[](int pos) const{
Pgina 61 de 85
Pgina 62 de 85
void
if(lines == 0) { table = new string*[1]; table[0]= new string((char*) s); _assert(!table[0],strexception(1,"void stringlist::add(const char* s)","falta de memria")); } else { string **tmp = new string*[lines + 1]; _assert(!tmp,strexception(1,"void stringlist::add(const char* s)","falta de memria")); for(i=0;i < lines;i++) tmp[i] = table[i]; _assert(!(tmp[i] = new string((char*) s)),strexception(1,"void stringlist::add(const char* s)","falta de memria")); delete []table; table = tmp; } lines++; } void stringlist::add(const string& s) { add(s._str); } void stringlist::add(const stringlist &list) { for(int i=0;i<list.count();i++) add(list[i]); } stringlist::stringlist(const char* s) { table = NULL; lines = 0; add(s); } stringlist::stringlist(const string& s) { table = NULL; lines = 0; add(s); } stringlist::stringlist(const stringlist& list) { table = NULL; lines = 0; add(list); }
_assert((pos < 0) || (pos >= lines),strexception(2,"void stringlist::remove(int pos) {","ndice fora de limites")); string** tmp = new string*[lines-1]; _assert(!tmp,strexception(1,"void stringlist::remove(int pos) {","falta de memria")); for(i=0;i < lines;i++) { if(i != pos) tmp[j++] = table[i]; } delete table[pos]; // apaga a string da tabela delete []table; table = tmp; lines--; } void stringlist::slice(int min, int max) { int tmp; if(min > max) { tmp = max; max = min; min = tmp; // permuta os valores ;) } _assert((min < 0) || (min >=lines) || (max < 0) || (max >= lines),strexception(2,"void stringlist::slice(int min, int max)","ndice fora de limites")); if((min == 0) && (max == lines-1)) { clear(); // no pior dos casos limpa o contedo ;) return; } for(int i=min; i <= max; i++) { remove(min); } } void } void stringlist::load(const char* fn) { ifstream in(fn); string tmp; stringlist::load(const string& fn) { stringlist::load(fn._str);
_assert(in.fail(),strexception(6,"void stringlist::load(const char* fn)","ficheiro no encontrado")); clear(); do { in>> tmp; _assert(in.fail(),strexception(3,"void stringlist::load(const char* fn)","erro de leitura do ficheiro")); add(tmp); } while (in.get() != EOF); remove(lines-1); }
Pgina 63 de 85
Pgina 64 de 85
void
void }
stringlist::split(const string& what, const string& sep) { split(what._str,sep._str); stringlist::split(const char* what, const string& sep) { split(what,sep._str);
_assert(out.fail(),strexception(4,"void stringlist::save(const char* fn) const","erro a escrever no ficheiro")); for(int i=0; i < lines; i++) { out << table[i] << endl; _assert(out.fail(),strexception(4,"void stringlist::save(const char* fn) const","erro a escrever no ficheiro")); } } void stringlist::insert(int pos, const char* s) { int i,j=0;
void } void
_assert((pos < 0) || (pos > lines),strexception(2, "void stringlist::insert(int pos, const char* s)","ndice fora dos limites")); if(pos == lines) { add(s); return; } if(pos < 0) pos = 0; if(lines == 0) { add(s); return; } string** tmp = new string*[lines+1]; _assert(!tmp,strexception(1,"void stringlist::insert(int pos, const char* s)","falta de memria")); for(i=0; i <= lines; i++) { if(i != pos) tmp[i] = table[j++]; else _assert(!(tmp[i] = new string((char*) s)),strexception(1,"void stringlist::insert(int pos, const char* s)","falta de memria")); } delete []table; table = tmp; lines++; } void } void stringlist::insert(int pos, const string& s) { insert(pos,s._str); stringlist::insert(int pos, const stringlist& list) { for(int i=pos; i < pos+list.count(); i++) { insert(pos,list[pos+list.count()-1-i]); } stringlist::split(const string& what, const char* sep) { split(what._str,sep);
} void
stringlist::split(const char* what, const char* sep) { char *str; clear(); if(!what || !sep) return; while((str=strstr(what,sep))) { *str = 0; add(what); *str = sep[0]; what = str + strlen(sep); } add(what); stringlist::join(const char* sep) { string tmp(""); for(int i=0; i< lines; i++) { if(i) tmp += (char *)sep + *table[i]; else tmp += *table[i]; // o primeiro caso especial ;) } clear(); add(tmp); stringlist::join(const string& sep) { join(sep._str); stringlist::replace(const char* what, const char* for_what) { // ainda por implementar
} void }
Pgina 65 de 85
Pgina 66 de 85
7. Apndice B
Pgina 67 de 85
Pgina 68 de 85
Pgina 69 de 85
Pgina 70 de 85
Pgina 71 de 85
Pgina 72 de 85
Pgina 73 de 85
Pgina 74 de 85
Pgina 75 de 85
Pgina 76 de 85
Pgina 77 de 85
Pgina 78 de 85
Pgina 79 de 85
Pgina 80 de 85
Pgina 81 de 85
Pgina 82 de 85
Pgina 83 de 85
Pgina 84 de 85
9.1 Identificao
Nuno Manuel Almeida Loureiro n. 2810 Henrique Manuel Canrio Cardoso n. 3485 Fernando Jos Belo n. 3424 1 turno 1 turno 1 turno
9.2 Observaes
9.3 Classificao
Valores
9.4 O docente
(Paulo Moiss, Eng) Pgina 85 de 85