Ficheiros C - Verificar se um ficheiro existe no disco

Julho 24, 2008

Este programa tenta abrir um ficheiro para verificar este existe no disco.


/* Verificar se um ficheiro existe */
#include <stdio.h>

#define buffer 3 + 1	/* Mais um caracter para o  */

int main(){

	FILE *fp;

	char s[buffer];

	printf("Introduza o Nome do Ficheiro [Máximo %d caracteres]:",buffer-1);

	fgets(s,buffer,stdin);

	/* Abrir o Ficheiro */

	fp = fopen(s,"r");

	/* Verificar se a abertura foi feita com sucesso */

        if (fp==NULL)
		printf("Impossível abrir o ficheiro %s\n",s);
	else{	printf("Ficheiro %s aberto com sucesso!!!\n",s);

                fclose(fp);

        }

        return 0;

}

Nota: O estilo de programação está mais visível na opção “view plain”


Definir idioma (locale) em Debian

Julho 24, 2008

Tive que perguntar e tomei nota aqui para não me esquecer :)

Como ver quais os locales instalados?

# locale -a
C
POSIX
en_US.utf8

Como adicionar um locale que não está instalado?

# dpkg-reconfigure locales

E já temos algo do tipo …

# locale -a
C
POSIX
en_US.utf8
pt_PT.utf8

Como activo/selecciono o novo locale?

# export LANG=pt_PT

Nota: Este exemplo foi dado no pressuposto de se estar a instalar o locale pt_PT.utf8


Implementação de uma pilha - struct array C++

Junho 8, 2008

Uma pilha é uma estrutura de dados que implementa a filosofia LIFO(Last In, First Out), ou seja, o último item a ser inserido na pilha é o primeiro a poder ser retirado, pois é o que se encontra por “cima”.

Uma analogia que pode ser feita consiste em pensar em termos de uma pilha de livros.

Se apenas conseguir manipular um livro de cada vez, como é que faço para obter o livro de baixo?

Sim, a resposta é ir desempilhando os livros de cima, um a um, até o livro pretendido ficar acessível.

São muitas as formas de implementação de pilhas e nas mais variadas linguagens de programação.

A que aqui vou abordar implementa uma pilha sobre uma estrutura com dois membros, um dois quais é um array que irá armazenar a pilha propriamente dita.

topo: É um inteiro que me indica a posição do topo da pilha. O valor -1 significa que a pilha está vazia.

item: É um array de inteiros de tamanho determinado por #define tamanho 5.

A imagem seguinte tenta ilustrar as operações que foram executadas na função main.

Por questões de simplificação as funções empilhar e desempilhar não efectuam por si só o teste às situações “pilha vazia” e “pilha cheia”, pelo que deverão ser invocadas em conjunto com as funções aqui disponibilizadas para esse efeito.

O que quero eu dizer?

  • Só se pode empilhar numa pilha que não está cheia.
  • Só se pode desempilhar numa pilha que não está vazia.

Código fonte: [ download ]

#include <iostream>
#define tamanho 5
using namespace std;
typedef struct{
      int topo ;
      int item [tamanho] ;
}PILHA;
void iniciaPilha (PILHA &p) {
     p.topo = -1 ;
}
bool pilhaVazia(PILHA p){
	if(p.topo == -1 )
		return true;
	else
		return false;
}
bool pilhaCheia(PILHA p){
	if (p.topo == tamanho-1)
		return true;
	else
		return false;
}
void empilha(PILHA &p, int x){
	p.item[++p.topo]=x;
}
int desempilha(PILHA &p){
	return (p.item[p.topo--]) ;
}
//O mais importante já passou.
//Este código agora é só para testar.
int main(){
	PILHA s ;
	//criar a pilha
	iniciaPilha (s);
	//Verificar que a pilha está vazia
	if(pilhaVazia(s))
		cout<<"A pilha está vazia."<<endl;
	else
		cout<<"A pilha não está vazia."<<endl;
	//empilhar três elementos
	empilha(s,12);
	empilha(s,33);
	empilha(s,7);
	empilha(s,11);
	//Verificar que a pilha está cheia
	if(pilhaCheia(s))
		cout<<"A pilha está cheia."<<endl;
	else
		cout<<"A pilha não está cheia.\n"<<endl;
	//desempilhar e mostrar um elemento
	cout<<"Item desempilhado: "<<desempilha(s)<<endl;
	//terminar

	return 0;
}

Eu não vou …

Maio 30, 2008

“O que mais preocupa não é o grito dos violentos, nem dos corruptos, nem dos desonestos, nem dos sem-carácter, nem dos sem-ética.

O que mais preocupa é o silêncio dos bons!”

Martin Luther King


Funções: Passagem de parâmetros por valor/referência em C/C++

Maio 19, 2008

Vou partir do princípio que todos sabem um pouco de linguagem C/C++ e que compreendem a forma de criação e utilização de funções. Também vou tentar escrever o mínimo possível e passar a ideia através de quatro exemplos muito simples, sempre à volta da clássica função troca.

Função Troca: recebe dois valores a e b, e troca os respectivos conteúdos.

Passagem de parâmetros por valor: A função recebe uma cópia da variável que é fornecida quando é invocada. Todas as alterações feitas dentro da função não vão afectar os valores originais.

Passagem de parâmetros por referência: Neste caso o que é enviado para a função é uma referência às variáveis utilizadas, e não uma simples cópia, pelo que as alterações realizadas dentro da função irão certamente alterar os valores contidos nessas variáveis.

Exemplo 1 - Passagem de parâmetros por valor - Linguagem C

#include<stdio.h>
void troca(int a, int b){
        int temp;
        temp=a;
        a=b;
        b=temp;
}
int main(){
        int a=2,b=3;
        printf("Antes de chamar a função :\na=%d\nb=%d\n",a,b);
        troca(a,b);
        printf("Depois de chamar a função:\na=%d\nb=%d\n",a,b);
        return 0;
}

Apesar da troca dentro da função, os valores originais não sofreram alterações.

Exemplo 2 - Passagem de parâmetros por referência - Linguagem C

Contradizendo o título, em C só existe a passagem de parâmetros por valor (obrigatório o uso de apontadores).

#include<stdio.h>
void troca(int *a, int *b){
        int temp;
        temp=*a;
        *a=*b;
        *b=temp;
}
int main(){
        int a=2,b=3;
        printf("Antes de chamar a função :\na=%d\nb=%d\n",a,b);
        troca(&a,&b);
        printf("Depois de chamar a função:\na=%d\nb=%d\n",a,b);
        return 0;
}

A troca dentro da função reflecte-se nos valores originais.

Exemplo 3 - Passagem de parâmetros por valor - Linguagem C++

#include<iostream>
using namespace std;
void troca(int a, int b){
        int temp;
        temp=a;
        a=b;
        b=temp;
}
int main(){
        int a=2,b=3;
        cout<<"Antes de chamar a função  :\na="<<a<<"\nb="<<b<<endl;
        troca(a,b);
        cout<<"Depois de chamar a função :\na="<<a<<"\nb="<<b<<endl;
        return 0;
}

Situação semelhante à apresentada no exemplo 1.

Exemplo 4 - Passagem de parâmetros por referência - Linguagem C++

#include<iostream>
using namespace std;
void troca(int &a, int &b){
        int temp;
        temp=a;
        a=b;
        b=temp;
}
int main(){
        int a=2,b=3;
        cout<<"Antes de chamar a função  :\na="<<a<<"\nb="<<b<<endl;
        troca(a,b);
        cout<<"Depois de chamar a função :\na="<<a<<"\nb="<<b<<endl;
        return 0;
}

Como se pode verificar, a evolução da linguagem C para C++ veio simplificar algumas tarefas :)


Apontadores em linguagem C – Noções elementares

Maio 17, 2008

Pressupostos: Conhecimentos elementares de programação em Linguagem C/C++ e do conceito de variável.

Objectivo: Compreender o conceito de apontador.

A ideia por detrás do conceito de apontador é muito simples, e assenta no facto de todas as variáveis serem armazenadas na memória RAM do computador, tendo obrigatoriamente que ficar associadas a um endereço de memória.

Quando num programa utilizamos a instrução int x=33; estamos a indicar ao compilador para reservar um espaço na memória para poder armazenar valores do tipo inteiro, com o número de bits associado a este para cada compilador e/ou arquitectura. Simultaneamente é atribuído o valor 33 à variável x, o que significa que no endereço de memória associado à variável x é armazenado o valor 33.

Daqui em diante sempre que pretendermos utilizar ou alterar o valor armazenado neste endereço de memória bastará utilizar uma referência ao nome da variável ( x ) para o efeito.

No exemplo apresentado ( int x=33; ) diz-se que foi realizada uma declaração seguida da inicialização (Inicialização automática).

Em termos gráficos, fica representado na figura seguinte o que se passa ao nível da memória do computador:


x



< - Nome da variável


33



< - Conteúdo

100

101

102

103

< - Endereço de memória

Notar que foi utilizado o endereço de memória 101(endereço fictício) para armazenar o valor 33. Isto significa apenas que a representação binária do número 33 é armazenada a partir do endereço 101 e ocupa um número de bits correspondente ao tipo de dados declarado.

Depois de chegados a este ponto podemos avançar para o conceito de apontador.

Um apontador é uma variável como qualquer outra, mas que é utilizada para armazenar o endereço de memória de outra variável.

A imagem seguinte representa a evolução do caso acima apresentado, acrescido da utilização de um apontador “ptr” que irá ser utilizado para manipular o conteúdo do endereço de memória onde se encontra armazenado o valor de x:


x


ptr

< - Nome da variável

33

101

< - Conteúdo

100

101

102

103

< - Endereço de memória

Acabamos de criar uma variável nova, mas agora trata-se de um apontador:

  • O nome do apontador é ptr.
  • O apontador ptr encontra-se armazenado na posição de memória 103.
  • O conteúdo de ptr é o endereço de memória da variável x.

Conclusão: ptr é um apontador para a variável x.

Vamos avançar com um exemplo com valores reais:

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
	int x=33;
	int *ptr_x=&x;
	cout << "-- Estado inicial ---------------------------------------\n";
	cout << "\tValor armazenado na variável x       : " << x << endl;
	cout << "\tEndereço de memória da variável x    : " << &x << endl;
	cout << "\tValor armazenado na variável ptr_x   : " << ptr_x << endl;
	cout << "\tEndereço de memória da variável ptr_x: " << &ptr_x << endl;

	cout << "-- Ler um novo valor para x ------------------------------\n";
	cout << "x = "; cin >> x;
	cout << "\tValor armazenado na variável x       : " << x << endl;
	cout << "\tEndereço de memória da variável x    : " << &x << endl;
	cout << "\tValor armazenado na variável ptr_x   : " << ptr_x << endl;
	cout << "\tEndereço de memória da variável ptr_x: " << &ptr_x << endl;

	return 0;
}
Download do código fonte: http://www.box.net/shared/kmxz8obkg8

Comentários linha-a-linha: Apenas me vou referir ao que interessa abordar sobre este assunto.

Linha 5: Como já referi, esta linha de código faz a inicialização automática da variável x, do tipo inteiro, com o valor inicial 33.

Linha 6: Para compreender o que se passa nesta linha é necessário conhecer os operadores unários * e & .

De forma simplista temos:

  • & significa “endereço de”.
  • * significa “aponta para”, ou se quisermos, “conteúdo do endereço apontado por”.

Foi então criado um apontador ptr. cujo conteúdo foi automaticamente inicializado com o valor correspondente ao endereço de memória da variável x.

Note-se que a posição do caracter * pode ser feita de outras formas, tal como demonstrado a seguir, mas a primeira é a mais utilizada.

int *ptr;
int* ptr;
int * ptr;

Restantes linhas: Servem apenas para ir mostrando o que se passa com estas variáveis no decorrer da execução deste pequeno programa.

Nota final: Espero ter conseguido passa a mensagem sobre o que são os apontadores, mas termino recordando que este é uma assunto muito vasto e que muito fica por dizer, mas sem se compreender bem o que aqui foi dito não adianta muito avançar.


Linguagem C - Como transferir dados por ip?

Maio 9, 2008

Antes de tudo é preciso assumir que estamos perante uma pergunta que nos conduz inevitavelmente a uma área de alguma complexidade.
Quando me surgiu esta ideia acabei neste endereço ( http://beej.us/guide/bgnet/output/html/multipage/index.html ), onde de facto está tudo muito claro. Parabéns ao autor Brian “Beej Jorgensen” Hall.
Mas imagine que, sem querer atravessar todo o processo de estudo de comunicação de dados em linguagem C, pretende escrever um programa que necessita de trocar pequenas quantidades de informação sem grandes preocupações de segurança?

Proponho um exemplo: “O Jogo do Galo”!

Numa análise simplista, para implementar este jogo em rede basta conseguir trocar dados do tipo “char” que representem as várias situações: ‘x’ para as cruzes; ‘o’ para as bolas; ‘ ‘ para uma célula vazia; e todos os outros caracteres para associar às várias situações de controlo que necessitem.
Sem explorar os aspectos básicos associados à implementação deste jogo, deixo aqui um pequeno programa de exemplo, onde implementei duas funções que tornam possível a comunicação entre dois “hosts” na vossa rede, bastando paro o efeito conhecer o endereço ip que lhes está atribuído.
A função “enviar” faz justiça ao nome escolhido, pois simplesmente lança no meio de transmissão um sinal dirigido ao “ip_receptor” contendo um caracter. O receptor faz com o caracter o que lhe apetecer!
A função “receber” ausculta o meio de transmissão até lhe ser enviado um caracter.
A função “main” é “paisagem”, pois apenas serve para exemplificar a utilização destas duas funções.

Download do código fonte: aqui (Box: sourcecode0004.cpp)
Basta mudarem os endereços ip para o vosso caso e já estão a trocar caracteres.
Espero que isto vos seja útil e fico à espera desse “Jogo do Galo – Versão rede :)”


Como publicar Código Fonte

Maio 1, 2008

Desde que iniciei este blog andava com uma dificuldade que já me estava a irritar.
Apesar de ser defensor de que o código fonte em qualquer Linguagem de Programação deve ser fiel a um estilo definido por cada programador e escolhido de forma a ser o mais universal possível e evidenciar as várias estruturas nele utilizadas, não estava a conseguir este efeito no WordPress.
Agora de repente encontrei uma forma simples de o fazer e vou aqui partilhá-la.
Basta colarem o vosso código entre as tags:

[sourcecode language='css']…[/sourcecode].

O efeito é este:
#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[]){
    QApplication app(argc, argv);
    QLabel *texto = new QLabel("Bom dia QT!");
    texto->show();
    return app.exec();
}

Giro não é?

Fonte: http://faq.wordpress.com/2007/09/03/how-do-i-post-source-code/


Formatação básica de “output” em Linguagem C++

Abril 22, 2008

Objectivo: Realizar formatações elementares de formatação de “output” em linguagem C++, utilizando os manipuladores de saída.

Pressupostos: Conhecimentos elementares sobre utilização da Biblioteca de streams do C++.

Organização: Serão apresentados pequenos exemplos de formatação de “output”, acompanhados de uma breve explicação/comentário/sugestão.

Exemplo 1: Quando pretendemos que um número ocupe um número específico de colunas(caracteres).

Código fonte

(Box.Net: sourcecode0001.cc )

Output

123.456

***123.456

123.456

Comentários

Linha 1 do output – o número vai ocupar exactamente 10 caracteres e o espaço sobrante é preenchido por defeito com o caracter espaço.

Linha 2 do output – o mesmo que no caso anterior, mas alterando previamente o caracter de preenchimento para um ‘*’.

Linha 3 do output – Como os manipuladores de output não conseguem lidar com o número, a sua função é ignorada.

Exemplo 02: Dado um número inteiro representado no sistema de numeração decimal, escrever o correspondente nos sistemas de numeração hexadecimal e octal.

Código fonte

( Box.Net: sourcecode0002.cc )

Output

Decimal : 123

Hexadecimal: 7b

Octal : 173

Comentários

Como facilmente podem constatar, basta escrever hex ou oct entre o cout e o valor decimal, funcionando como uma espécie de “filtro”.

Notem que hex e oct são manipuladores, tal como o endl que temos utilizado sem lhe fazer qualquer referência especial.

Exemplo 03: Formatar a saída de uma série de registos com formatos e tipos distintos, contendo os seguintes dados relativos a pessoas: nome, idade e altura.

Código fonte

( Box.Net: sourcecode0003.cc )

Output

Nome Idade Altura
Catia Vanessa 17 1.75
Manuel Catarino 5 0.75

Comentários

Experimentem eliminar os manipuladores left e right.


Andrew S. Tanenbaum veio a Portugal

Abril 19, 2008

Muito recentemente, quando ganhou forma o meu interesse por estas coisas do “Linux”, rapidamente me comecei a cruzar com uma série de nomes dos GRANDES SENHORES dos Sistemas Operativos.

Um deles, o pai do Minix, de nome Andrew S. Tanenbaum, esteve recentemente no nosso país.

Fiquei a saber disto à pouco ao ler por acidente o número 150, de Maio 2008, da PCGuia, revista que assinei à muito tempo e que depois desisti por se parecer muito com um catálogo de compras, o que aliás se passa com a maioria delas.

Mas pronto … comprem a revista e leiam o que diz o SENHOR … é interessante.

Palavras soltas …

“…A minha grande esperança é que, um destes dias, haja um enorme desastre de computadores que envolva o Windows e que faça realmente estragos …”

“…Porque razão estranha, convencionou-se que se o software não funcionar a culpa não é do fabricante desse software. …”

“…Estamos numa fase em que vende a política do “mais é melhor”, mas não creio que os utilizadores pediram esta tendência e nem tampouco a compreendem…”

“… O Linux tem um kernel que não pára de crescer, ao ponto de se começar a parecer com o Windows…”

“…O Linux é obsoleto e digo-o com uma convicção cada vez maior…”

“…Cheguei a pensar que o FreeBSD viria a dominar o mundo…”

Claro que estas são apenas algumas frases que devem ser lida no contexto, mas acho o ponto de vista interessante!