sexta-feira, 24 de junho de 2011

Arrays bidimensionais

Olá pessoal,

hoje vamos tentar trabalhar um pouco com arrays bidimensionais, mais especificamente em como passá-los como parâmetros de funções.

Para isso vamos escrever duas funções, uma para imprimir um array e outra para preencher.

No exemplo vamos utilizar um array de 3 por 4.


void ImprimeMatriz(int matriz[][4], int linha)
{
    int c_linha; //conta linhas
    int c_coluna;//conta colunas
    int coluna = 4;
    for(c_linha = 0; c_linha < linha; c_linha++)
    {
        printf("\n");
        for(c_coluna = 0; c_coluna < coluna; c_coluna++)
            printf("%d ", matriz[c_linha][c_coluna]);
    }

}

void PreencheMatriz(int matriz[][4], int linha)
{
    int contador = 0;
    int c_linha; //conta linhas
    int c_coluna;//conta colunas
    int coluna = 4;
    for(c_linha = 0; c_linha < linha; c_linha++)
    {
        for(c_coluna = 0; c_coluna < coluna; c_coluna++)
            matriz[c_linha][c_coluna] = contador++;
    }
}

Veja que, temos que passar o tamanho da linha como parâmetro da matriz, vejas as assinaturas: void PreencheMatriz(int matriz[][4], int linha) e void ImprimeMatriz(int matriz[][4], int linha)

Bom, isso porque na verdade é passado o endereço do array, e o C precisa saber até onde ele pode ir na linha.

Outra possibilidade é utilizarmos aritmética de ponteiros, na verdade, um array é um conjunto contínua na memória, assim por exemplo, se o endereço inicial é 10, e um inteiro ocupar 2 bytes temos que o primeiro elemento está no endereço 10, o segundo no endereço 12, o terceiro no 14.... Isso deve ser bem observado, por exemplo para chegar no endereço 12, se nosso endereço base é 10, fazemos a seguinte operação com nosso ponteiro: ponteiro +1, ou seja, o + 1 diz que vamos para o próximo endereço, com o passo de acordo com nosso tipo, que no exemplo é int e assumimos que ele é de 2 bytes. Vejamos abaixo uma função que vai fazer esse tipo de operação para imprimir nosso array:

void ImprimeMatrizPonteiros(int * matriz, int tamanho)
{
    int cont = 0;
    for (cont = 0; cont < tamanho; cont ++)
    {
        printf("% d", *(matriz + cont));
    }
}

Nosso método main:

int main()
{
    int matriz[3][4];
    PreencheMatriz(matriz,3);
    ImprimeMatriz(matriz,3);
    printf("\nVamos usar apenas ponteiros:\n");
    ImprimeMatrizPonteiros(matriz[0],12);


    return 0;
}

que irá reproduzir a seguinte saída:

segunda-feira, 13 de junho de 2011

Interagindo com o sistema

Vamos tentar enviar alguns comandos para a linha de comando, dentro de nosso programa em C. O programa foi criado e testado em um sistema Debian.

Vamos ao código:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
int  MostraOpcoes()  //mostra as opções que vamos implementar e retorna o valor digitado pelo usuário
{
    int opcao;
    printf("\n1 - Lista diretorios");
    printf("\n2 - Cria diretorio");
    printf("\n3 - Cria arquivo");
    printf("\n4 - Deleta diretorio");
    printf("\n\tDigite a opcao:\t");
    scanf("%d",&opcao);

    return opcao;
}

void ExecutaComandos(int opcao)
{
    char dir[50], cmd[50];
    int op;
    int ret;
    struct stat files;
    FILE * arquivo;
    switch(opcao)
    {
        case 1: printf("\n\tListando\n"); //apenas lista o diretório
                system("ls -la"); //usamos o comando system que enviará o comando para o sistema
                break;
        case 2: printf("\n\tCriando Diretorio\n"); //vamos ler o nome do diretório a ser criado
                printf("\n\tInforme o nome do diretorio: ");
                scanf("%s",dir);
                sprintf(cmd, "mkdir %s",dir);
                if(stat(dir,&files)==0) //Vamos verificar se ele existe
                {
                    printf("\nO arquivo ja existe!!!\nDeseja Remove-lo? 1-Sim\t");
                    scanf("%d", &op);
                    if(op == 1) //caso ele existe e o usuário desejar apagar, vamos remover o diretório e criar novamente
                    {
                        sprintf(cmd,"rm -r %s",dir);  //cmd recebe a string rm -r + o conteúdo de "dir"
                        system(cmd);
                        sprintf(cmd, "mkdir %s",dir);
                        system(cmd);
                    }
                }

                else
                    ret = system(cmd);


                break;
        case 3: printf("\n\tInforme o nome do arquivo:\t"); //vamos criar um arquivo
                scanf("%s",dir);
                arquivo = fopen(dir,"r"); //aqui é simples, usamos fopen com opção 'r' assim se o arquivo existir vamos informar ao usuário
                if (arquivo != NULL)
                    printf("\nO arquivo ja existe");
                else
                    arquivo = fopen(dir,"w"); //se não existir o criamos
                break;
                fclose(arquivo);

        case 4: printf("\n\tInforme o nome do diretorio:\t"); //apenas excluiremos o diretório
                scanf("%s", dir);
                if(stat(dir,&files)==0)
                {
                    sprintf(cmd,"rm -r %s",dir);
                    system(cmd);
                }
                else
                printf("\nArquivo inexistente!!\n");
                break;
    }

}

int main()
{
    int opcao;
    int continua;
    do
    {
        opcao = MostraOpcoes();
        ExecutaComandos(opcao);
        printf("\n\tPressione 0 para sair:\t");
        scanf("%d",&continua);
    }while(continua !=0);
    return 0;
}

Expressões Regulares em C#

Hoje vamos falar de expressões regulares em C#. O objetivo será:


  • Contar o número de palavras em um arquivo
  • Contar o número de ocorrências de uma determinada palavra

Bom para isso vamos iniciar o Visual Studio e dar início ao trabalho:

Vamos montar a seguinte tela:


Bom vamos programar uma classe, para trabalhar com nosso arquivo. Vamos chamá-la de File.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace ContaPalavrasArquivo
{
class File
{
StreamReader arq; //vai ser usado para ler o arquivo
public File(string caminho) //nosso construtor que recebe o caminho do arquivo
{
arq = new StreamReader(caminho,Encoding.Default);
}
public void readFile(TextBox texto) //lê o arquivo e mostra no TextBox
{
string linha;
do
{
linha = arq.ReadLine();
if (linha != null)
texto.Text = texto.Text + linha + System.Environment.NewLine;
} while (linha != null);
}

public int contaPalavras(TextBox text) //Conta palavras
{
int nPalavras = 0;
string linha;
MatchCollection exp; //vai armazenar o número de ocorrências
linha = text.Text;
if (linha != null)
{
exp = Regex.Matches(linha, @"[\S]+"); //expressão regular para espaços em branco
nPalavras = exp.Count;
}
return nPalavras;
}
//vai contar o número de ocorrências do texto. Para isso, vamos passar o texto que //está no textBox, vamos passar a string que desejamos comparar, e uma variável do //tipo boll que irá indicar se desejamos ou não diferenciar maiúsculas de minúsculas
public int contaOcorrencias(TextBox text, string palavra, bool ignoreCase)
{
MatchCollection exp;
if(ignoreCase)
exp = Regex.Matches(text.Text, palavra,RegexOptions.IgnoreCase);
else
exp = Regex.Matches(text.Text, palavra);
return exp.Count;

}
}
}


Vamos programar o nosso menu:

Vale ressaltar que temos duas variáveis que possuem acesso em todo nosso programa, que devem ser declaradas da seguinte forma:

String caminho;
File arquivo;

Vamos ao código:

private void abrirToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog UI = new OpenFileDialog(); //Vamos abrir uma caixa para ir //diretamente ao arquivo
UI.Filter = "txt files (*.txt)|*.txt";
UI.InitialDirectory = "C:";
UI.Title = "Selecione um arquivo";
if (UI.ShowDialog() == System.Windows.Forms.DialogResult.OK)
caminho = UI.FileName;
else
caminho = null;
if (caminho != null)
{
arquivo = new File(caminho); //criamos a instância de nossa classe
arquivo.readFile(textBoxTexto); //lemos o arquivo que será colocado no //textBoxTexto
}
}



Quando utilizarmos nosso menu irá aparecer um dialogbox como este:



Perfeito, agora depois de abrir o arquivo teremos uma tela como a que segue:




Vamos codificar nosso botão “Conta”

private void buttonContaPalavras_Click(object sender, EventArgs e)
{
int contador = arquivo.contaPalavras(textBoxTexto);
textBoxNPalavras.Text = contador.ToString();
}

Vamos codificar o botão “Conta Ocorrencias”.

Primeiramente vamos adicionar outro form, para que quando clicarmos em “Conta Ocorrencias” nos seja mostrado um form para digitar a palavra que estamos procurando.


Esse form, terá duas variáveis públicas que irão nos ajudar a trabalhar, são elas:

public string palavra;
public bool ignoreCase;

Veja o código do form:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ContaPalavrasArquivo
{
public partial class ContaOcorrencias : Form
{
public string palavra;
public bool ignoreCase;
public ContaOcorrencias()
{
InitializeComponent();
}

private void buttonContaOcorrencias_Click(object sender, EventArgs e)
{
palavra = textBoxPalavra.Text;
if (checkBoxDifMaiuscula.Checked == true)
ignoreCase = false;
else
ignoreCase = true;
this.Close();
}
}
}

Agora sim, vamos codificar nosso botão “Conta Ocorrencias”

private void button1_Click(object sender, EventArgs e)
{
ContaOcorrencias formContaOcorrencias = new ContaOcorrencias();
formContaOcorrencias.ShowDialog();
string palavra = formContaOcorrencias.palavra;
int contador = arquivo.contaOcorrencias(textBoxTexto, palavra, formContaOcorrencias.ignoreCase);
textBoxNOcorrencias.Text = contador.ToString();

}
Bom, executando temos os seguintes resultados:






sábado, 4 de junho de 2011

Métodos não estáticos

Olá Pessoal, hoje vamos focar em outra linguagem de programação, a linguagem Csharp. Vamos ver a diferença entre métodos estáticos e métodos não estáticos.

Para isso, vamos criar uma classe, chamada "operacoes", nela vamos inserir dois métodos, o primeiro o método estático chamado "soma" e o segundo, que não é estático, chamado "subtracao".


Veja a classe abaixo:

class operacoes
{
public static int soma(int numero01, int numero02)
{
return numero01 + numero02;
}

public int subtacao(int numero01, int numero02)
{
return numero01 - numero02;
}
}


Bom, agora, vamos definir um form com o layout como o abaixo:


Vamos clicar no botão "Soma" e colocar o seguinte código dentro dele:

textBoxResultSoma.Text = operacoes.soma(int.Parse(textBoxSomaN1.Text), int.Parse(textBoxSomaN2.Text)).ToString();



Assim, quando informarmos os valores para "Num 1" e "Num 2" teremos a soma dos dois números, como segue:



Agora, vamos realizar a operação de subtração. Para isso, vamos colocar o seguinte código, no botão "Subtração"

operacoes op = new operacoes();

textBoxResultSub.Text = op.subtacao(int.Parse(textBoxSubN1.Text), int.Parse(textBoxSubN2.Text)).ToString();




Veja a diferença, precisamos instanciar um novo objeto, para termos acesso a operação de subtração, pois a mesma não é estática, forçando o uso do operador "new" para instanciarmos um novo objeto.