levanta men to
DESCRIPTION
Levantamento de dadosTRANSCRIPT
)
{
FILE * pFile;
int c;
int n = 0;
pFile = fopen ("ArquivoTexto.txt", "r");
if (pFile !=NULL)
{
do { //DO
c = fgetc(pFile);
if (c == '\n') n++;
} //DO
while (c != EOF);
fclose(pFile);
printf("Número de linhas = %d.\n", n);
}
return 0;
}
#include <stdio.h>
int main ()
{
FILE * pFile;
int c;
int n = 0;
pFile = fopen ("ArquivoTexto.txt", "r");
if (pFile !=NULL)
{
do { //DO
c = fgetc(pFile);
if (c == '\n') n++;
} //DO
while (c != EOF);
fclose(pFile);
printf("Número de linhas = %d.\n", n);
}
return 0;
}
Listagem 1. Exemplo de programa em Linguagem C para contagem de linhas de um arquivo.
O Desafio
Partido do exemplo anterior de contagem simples de linhas de um arquivo texto, o desafio desta tarefa tem início ao se querer determinar o número de linhas do código que são comentários formatados segundo a sintaxe da Linguagem C/C++. A sintaxe prevê dois tipos de comentários: linha única começando com os caracteres “//” (barra, barra); e comentários multi-linhas começando com “/*” (barra, asterisco) e com término determinado por “*/” (asterisco, barra).
Para uma visão de um problema real, considere o exemplo de código fonte escrito em C apresentado na Listagem 2. Observe os vários trechos com comentários para ajudar a documentação do código-fonte.
Listagem 2. Exemplo real de código fonte com vários comentários.
//----------------------------------------------------------
// Exemplo de Cabeçalho
//
// Neste tipo de comentário, faz-se uma breve apresentação do conteúdo do
// módulo em linguagem C. O código apresentado a seguir é um extrato de
// desenvolvimento criado para a disciplina de Classificação e Pesquisa.
// Pede-se ao leitor identificar os tipos de linhas com comentários, em
// especial a diferenciação de comentários de uma ou de várias linhas.
//
// Autor: Marcelo Augusto Cicogna.
// Revisões:
// 22/11/2005: Criação do módulo.
// 01/11/2006: Expansão do módulo em função da lista de exercícios.
//----------------------------------------------------------
#include "TBinTree.h"
#include <stdio.h>
//----------------------------------------------------------
// Funcões de manipulação do tipo TBinTree.
//----------------------------------------------------------
TBinTree*
binTreeCreate(TData* pData)
/** Função para criação de uma nova árvore binária. É necessário fornecer um
valor para o primeiro nó.
@param pData variável do tipo TData para compor o nó raíz (root).
@return ponteiro para uma árvore binária.
@see BinTree.#dataCopy dataCopy()
@version 1.01
@author Marcelo Augusto Cicogna
*/
//----------------------------------------------------------
// Exemplo de Cabeçalho
//
// Neste tipo de comentário, faz-se uma breve apresentação do conteúdo do
// módulo em linguagem C. O código apresentado a seguir é um extrato de
// desenvolvimento criado para a disciplina de Classificação e Pesquisa.
// Pede-se ao leitor identificar os tipos de linhas com comentários, em
// especial a diferenciação de comentários de uma ou de várias linhas.
//
// Autor: Marcelo Augusto Cicogna.
// Revisões:
// 22/11/2005: Criação do módulo.
// 01/11/2006: Expansão do módulo em função da lista de exercícios.
//----------------------------------------------------------
#include "TBinTree.h"
#include <stdio.h>
//----------------------------------------------------------
// Funcões de manipulação do tipo TBinTree.
//----------------------------------------------------------
TBinTree*
binTreeCreate(TData* pData)
/** Função para criação de uma nova árvore binária. É necessário fornecer um
valor para o primeiro nó.
@param pData variável do tipo TData para compor o nó raíz (root).
@return ponteiro para uma árvore binária.
@see BinTree.#dataCopy dataCopy()
@version 1.01
@author Marcelo Augusto Cicogna
*/
{
TBinTree* binTree = malloc(sizeof(TBinTree));
if (binTree != NULL)
{ //Alocação do node raíz.
TNodeBin* pNode = nodeCreate();
//Copia no novo nó o valor data passado como parâmetro.
dataCopy(pNode->pData, pData);
//Associa o novo nó ao root da árvore binária.
binTree->root = pNode;
}
return (binTree);
}
//-----------------------------------------------------------
void
binTreeInsertNode(TNodeBin* pNode, TData* pData)
/** Função para inserção de um novo nó em uma árvore binária.
Função recursiva por meio do parâmetro pNode.
@param pNode ponteiro para um nó da árvore binária.
@param pData ponteiro para uma variável do tipo TData a ser inserida.
@return Não há retorno
@see BinTree.#dataCopy dataCopy()
@version 1.01
@author Marcelo Augusto Cicogna
*/
{
TNodeBin* pNodeAux;
if (pNode != NULL)
{ //Se for para inserir do lado esquerdo.
if ( dataComp(pData, pNode->pData, 0) < 0 )
{ //Inserir se o arco esquerdo for nulo.
if (pNode->esq == NULL)
{
pNodeAux = nodeCreate(); //Este é um exemplo de comentário
dataCopy(pNodeAux->pData, pData); //que ocorre junto com código.
pNode->esq = pNodeAux; //Será necessário um tratamento.
}
//Caso contrário, tentar inserir na sub-árvore a esquerda (recursivo).
else
binTreeInsertNode(pNode->esq, pData);
}
//Se for para inserir do lado direito.
else
{
TBinTree* binTree = malloc(sizeof(TBinTree));
if (binTree != NULL)
{ //Alocação do node raíz.
TNodeBin* pNode = nodeCreate();
//Copia no novo nó o valor data passado como parâmetro.
dataCopy(pNode->pData, pData);
//Associa o novo nó ao root da árvore binária.
binTree->root = pNode;
}
return (binTree);
}
//-----------------------------------------------------------
void
binTreeInsertNode(TNodeBin* pNode, TData* pData)
/** Função para inserção de um novo nó em uma árvore binária.
Função recursiva por meio do parâmetro pNode.
@param pNode ponteiro para um nó da árvore binária.
@param pData ponteiro para uma variável do tipo TData a ser inserida.
@return Não há retorno
@see BinTree.#dataCopy dataCopy()
@version 1.01
@author Marcelo Augusto Cicogna
*/
{
TNodeBin* pNodeAux;
if (pNode != NULL)
{ //Se for para inserir do lado esquerdo.
if ( dataComp(pData, pNode->pData, 0) < 0 )
{ //Inserir se o arco esquerdo for nulo.
if (pNode->esq == NULL)
{
pNodeAux = nodeCreate(); //Este é um exemplo de comentário
dataCopy(pNodeAux->pData, pData); //que ocorre junto com código.
pNode->esq = pNodeAux; //Será necessário um tratamento.
}
//Caso contrário, tentar inserir na sub-árvore a esquerda (recursivo).
else
binTreeInsertNode(pNode->esq, pData);
}
//Se for para inserir do lado direito.
else
{ //Inserir se o arco direito for nulo.
if (pNode->dir == NULL)
{
pNodeAux = nodeCreate();
dataCopy(pNodeAux->pData, pData);
pNode->dir = pNodeAux;
}
//Caso contrário, tentar inserir na sub-árvore a direita (recursivo).
else
binTreeInsertNode(pNode->dir, pData);
}
}
}
//-----------------------------------------------------------
{ //Inserir se o arco direito for nulo.
if (pNode->dir == NULL)
{
pNodeAux = nodeCreate();
dataCopy(pNodeAux->pData, pData);
pNode->dir = pNodeAux;
}
//Caso contrário, tentar inserir na sub-árvore a direita (recursivo).
else
binTreeInsertNode(pNode->dir, pData);
}
}
}
//-----------------------------------------------------------
Como resultado a ser conquistado, espera-se poder utilizar um aplicativo auxiliar para contar as linhas do arquivo “Exemplo.c” (ou de outro que o aluno achar conveniente durante a fase de testes). Veja um exemplo do provável funcionamento de tal programa.
Figura 1. Exemplo de uso e funcionamento do contador de linhas de código fonte.
Note-se que o programa “CodeCount” possui um parâmetro “–c” ou “-comment” que permite ao usuário decidir a contagem, ou não, das linhas com comentários. Vale lembrar que no arquivo Exemplo.c, existe uma linha vazia entre os dois “#include”. Além disso, as linhas que terminam um comentário multi-linhas com “*/” não são contadas como linhas em branco, mas também não são contadas como linhas de comentário.
Permite-se aos alunos e professores encontrarem outras regras de contagem. Esta atividade adotou algumas regras, mas elas não precisam ser as únicas durante a fase de desenvolvimento.
ETAPA № 1
Esta atividade é importante para que você compreenda os requisitos do problema e determine uma organização inicial do código fonte que permita o desenvolvimento de uma solução.
Para realizá-la é importante seguir os passos descritos.
PASSOS
Passo 1
Leia atentamente o desafio e os conceitos de contagem de linhas. Identifique os dois tipos principais de comentários possíveis em linguagem C: comentário de uma linha apenas, que começa com “//”; e comentários multi-linhas determinado por “/*” e “*/”.
Passo 2
Analise o problema e faça sugestões de como organizar o código em uma função principal (main) e uma outra função que fará a contagem das linhas dado como parâmetro o nome do arquivo a ser pesquisado. Pode-se chamar esta função de ccRun.
Observação: ao utilizar o prefixo “cc” (de Code Count), ou qualquer outro que o aluno achar conveniente, facilita-se a integração do código desenvolvido nesta tarefa com outras que o programador venha a achar necessário no futuro.
Como guia para alunos e professores, os autores deste desafio determinaram dois módulos para a solução do problema.
O módulo principal foi denominado MainCodeCount e um módulo auxiliar com funções de auxílio ao principal chamado LibCodeCount. Ao mesmo tempo, foram projetadas duas funções, conforme a orientação anterior. Os cabeçalhos e os nomes dos arquivos os quais conterão o código fonte são apresentados na Figura 2.
Arquivo MainCodeCount.c
int main(int argc, char *argv[])
{...
}
Arquivo LibCodeCount.h
void ccRun(char* file, int* nLines, int* nLinesComment, int* nLinesEmpty,int noComment, int silent);
Arquivo LibCodeCount.c
void ccRun(char* file, int* nLines, int* nLinesComment, int* nLinesEmpty, int noComment, int silent);
{...
}
Arquivo MainCodeCount.c
int main(int argc, char *argv[])
{...
}
Arquivo LibCodeCount.h
void ccRun(char* file, int* nLines, int* nLinesComment, int* nLinesEmpty,int noComment, int silent);
Arquivo LibCodeCount.c
void ccRun(char* file, int* nLines, int* nLinesComment, int* nLinesEmpty, int noComment, int silent);
{...
}
Figura 2. Exemplo de uso e funcionamento do contador de linhas de código fonte.
Estude a modularização proposta. É importante que seu código siga a organização sugerida nesta atividade, ou seja, que possua pelo menos dois módulos: um principal e outro auxiliar. Não será aceito na avaliação desta etapa a apresentação de apenas um arquivo de código fonte (arquivo.c).
Passo 3
Entregue o código fonte formado por dois módulos que contenham a função principal e uma função auxiliar para o cálculo do número de linhas, considerando as opções fornecidas nesta etapa.
Arquivo MainCodeCount.cpp
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include "LibCodeCount.h"
using namespace std;
int main(int argc, char *argv[])
{
int numeroLinhas, numeroComentarios, numeroVazias;
double porcentagemComentarios;
numeroLinhas = numeroComentarios = numeroVazias = 0;
if(argc < 2)
{
puts("\nUso correto: >MainCodeCount nomearquivo.ext [-c]");
}
else
{
printf("\n\tCode Count - Programmers Tool");
printf("\n\t Versao 1.0 - 2011");
printf("\n\n\tContagem para: "%s"", argv[1]);
if ((strcmp(argv[2], "-c") == 0) || (strcmp(argv[2], "-comment") == 0))
{
ccRun(argv[1], &numeroLinhas, &numeroComentarios, &numeroVazias, 0, 0);
printf("\n\tNumero de linhas..........: %i", numeroLinhas);
printf("\n\tNumero de linhas vazias...: %i", numeroVazias);
printf("\n\n\n");
}
else
{
ccRun(argv[1], &numeroLinhas, &numeroComentarios, &numeroVazias, 1, 0);
printf("\n\tNumero de linhas...................: %i", numeroLinhas);
printf("\n\tNumero de linhas com comentarios...: %i", numeroComentarios);
porcentagemComentarios = (numeroLinhas * numeroComentarios)/100;
printf("\n\tPorcentagem de comentarios.........: %2.1f%""%", porcentagemComentarios);
printf("\n\tNumero de linhas vazias............: %i", numeroVazias);
printf("\n\n\n");
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
Arquivo LibCodeCount.h
void ccRun(char* file, int* nLines, int* nLinesComment, int* nLinesEmpty,int noComment, int silent);
Arquivo LibCodeCount.cpp
#include <stdio.h>
#include <stdlib.h>
#include "LibCodeCount.h"
void ccRun(char* file, int* nLines, int* nLinesComment, int* nLinesEmpty,int noComment, int silent)
{
FILE * pFile;
int c1, c2;
int nL = 0, nLE = 0, nC = 0;
pFile = fopen (file, "r");
if (pFile !=NULL)
c1 = fgetc(pFile);
while (c1 != EOF)
{
if(c1 == '\n'){ nL++; }
if(c1 == '/')
{
c2 = fgetc(pFile);
if(c2 == '*')
{
do{
do{
c1 = fgetc(pFile);
if(c1 == '\n' && c1 != c2)
{
nC++;
nL++;
}
else if(c1 == '\n' && c2 == '\n'){ nLE++; }
c2 = c1;
}
while(c1 != '*');
c1 = fgetc(pFile);
}
while(c1 != '/');
}
if(c1 == '/' && c2 == '/'){ nC++; }
}
c2 = fgetc(pFile);
if(c2 == '\n' && c1 == '\n')
{
nLE++;
nL++;
}
c1 = c2;
}
fclose(pFile);
*nLines = nL;
*nLinesComment = nC;
*nLinesEmpty = nLE;
}
ArquivoTexto.txt
//------------------------------------------------------------
// Exemplo de Cabeçalho
//
// Neste tipo de comentário, faz-se uma breve apresentação do conteúdo do
// módulo em linguagem C. O código apresentado a seguir é um extrato de
// desenvolvimento criado para a disciplina de Classificação e Pesquisa.
// Pede-se ao leitor identificar os tipos de linhas com comentários, em
// especial a diferenciação de comentários de uma ou de várias linhas.
//
// Autor: Marcelo Augusto Cicogna.
// Revisões:
// 22/11/2005: Criação do módulo.
// 01/11/2006: Expansão do módulo em função da lista de exercícios.
//------------------------------------------------------------
#include "TBinTree.h"
#include <stdio.h>
//------------------------------------------------------------
// Funcões de manipulação do tipo TBinTree.
//------------------------------------------------------------
TBinTree*
binTreeCreate(TData* pData)
/** Função para criação de uma nova árvore binária. É necessário fornecer um
valor para o primeiro nó.
@param pData variável do tipo TData para compor o nó raíz (root).
@return ponteiro para uma árvore binária.
@see BinTree.#dataCopy dataCopy()
@version 1.01
@author Marcelo Augusto Cicogna
*/
{
TBinTree* binTree = malloc(sizeof(TBinTree));
if (binTree != NULL)
{
//Alocação do node raíz.
TNodeBin* pNode = nodeCreate();
//Copia no novo nó o valor data passado como parâmetro.
dataCopy(pNode->pData, pData);
//Associa o novo nó ao root da árvore binária.
binTree->root = pNode;
}
return (binTree);
}
//------------------------------------------------------------
void
binTreeInsertNode(TNodeBin* pNode, TData* pData)
/** Função para inserção de um novo nó em uma árvore binária.
Função recursiva por meio do parâmetro pNode.
@param pNode ponteiro para um nó da árvore binária.
@param pData ponteiro para uma variável do tipo TData a ser inserida.
@return Não há retorno
@see BinTree.#dataCopy dataCopy()
@version 1.01
@author Marcelo Augusto Cicogna
*/
{
TNodeBin* pNodeAux;
if (pNode != NULL)
{
//Se for para inserir do lado esquerdo.
if ( dataComp(pData, pNode->pData, 0) < 0 )
{
//Inserir se o arco esquerdo for nulo.
if (pNode->esq == NULL)
{
pNodeAux = nodeCreate(); //Este é um exemplo de comentário
dataCopy(pNodeAux->pData, pData); //que ocorre junto com código.
pNode->esq = pNodeAux; //Será necessário um tratamento.
}
//Caso contrário, tentar inserir na sub-árvore a esquerda (recursivo).
else
binTreeInsertNode(pNode->esq, pData);
}
//Se for para inserir do lado direito.
else
{
//Inserir se o arco direito for nulo.
if (pNode->dir == NULL)
{
pNodeAux = nodeCreate();
dataCopy(pNodeAux->pData, pData);
pNode->dir = pNodeAux;
}
//Caso contrário, tentar inserir na sub-árvore a direita (recursivo).
else
binTreeInsertNode(pNode->dir, pData);
}
}
}
//------------------------------------------------------------
Figura 3. Exemplo de uso e funcionamento do contador de linhas de código fonte.