• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

bakardi

duvidas na leitura de um ficheiro

9 mensagens neste tópico

Boas,

é o seguinte...ando a criar um programa que leia de um ficheiro determinados caracteres e caso nao encontre ele apresenta uma mensagem de erro...ai tudo bem ja consegui fazer isso,mas gostava que o programa ficasse mesmo perfeito e encontrasse todos os erros possiveis e um dos que na tou a conseguir resolver é este:

como eu disse em cima este programa vai ler de um ficheiro certos caracteres que sao T,P,N,S,C,E,R o que eu fiz foi uma comparaçao de strings so que se por exemplo eu a frente desse T pusser um "k" ou outro caracter,inteiro, float ele apresente um erro pois nessa mesma linha nao pode haver nada para alem de um dos 7 caracteres que indiquei em cima(T,P,N,S,C,E,R).

alguma sugestão quanto a isto?

a minha outra duvida é....ha alguma maneira de indicar que o numero de vertices é infinito?pois o ficheiro que o programa vai ler ira conter as coordenadas dos vertices bem como os vertices....e eu pus 1000000 vertices mas não sei se nao havera outra maneira de por. :hmm:

obrigado,

cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

> ele apresente um erro pois nessa mesma linha nao pode haver nada

> para alem de um dos 7 caracteres que indiquei

switch (ch) {
  case 'T': case 'P': case 'N': case 'S': case 'C': case 'E': case 'R':
    /* good character */
    break;
  default:
    /* bad character */
    fprintf(stderr, "erro");
    break;
}

> infinito?

Xiiiiiiiiiii ... isso é muito! acho que nem o Roadrunner ( http://en.wikipedia.org/wiki/IBM_Roadrunner ) aguenta.

O que podes fazer é usar "memória dinâmica". À medida que precisas de mais memória fazes um

malloc() ( http://www.opengroup.org/onlinepubs/007908799/xsh/malloc.html ) e metes lá os dados.

Assim, se precisares de 100 dados, só usas memória para 100 dados;

se precisares de 1000000 de dados, "só" usas memória para 1000000 de dados.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

eu ja tinha feito assim....obrigado a mesma pmg, sera que me podias  dizer(ou outro utilizador) atravez deste como altero isso de na mesma linha so poder haver um so caracter?

char comandos[200];				/* variável para onde são transferidas as linhas de texto do ficheiro*/
	char nome [200];				/*variável para onde é transferido o nome do objecto*/
char verificacao[200];				/*variável auxiliar na comtabilização do número de elementos de uma linha*/

int Comando_criacao, Rotacao_objecto_pt, Rotacao_objecto_cg, Translacao_objecto, Eliminacao_objecto, Geracao_fotograma, ampliacao, reducao;

int vertices,cor; 	

int coordenada_x, coordenada_y; 	

int i,erro; 					/*Declaração de dois inteiros ajudam na contabilização*/
float parametro_real;				/*Para evitar a proliferação de variáveis criou-se uma variável genérica do tipo float*/

FILE * fp;

fp=fopen ("/home/prog/projectocc/scene.scn", "r");

if (fp == NULL) {
	printf("\t<<<< ERRO: ficheiro inexistente >>>>\n");					/*Afere a existência do ficheiro no directório especificado*/
	exit (-1);
}


Comando_criacao = Rotacao_objecto_pt = Rotacao_objecto_cg = Translacao_objecto = Eliminacao_objecto = Geracao_fotograma = ampliacao = reducao = 0; 


			/* Se não for atribuido qualquer valor a estas variáveis, elas continuarão com o valor -200 o que originará um erro e consequente mensagem explicativa*/



while (fgets (comandos, 200, fp)!=NULL){								/*Percorre o ficheiro até ao fim*/


	char primeiro_elemento [30]="inicializar_a_variavel";	
	vertices = cor = -200;
	sscanf (comandos, "%s", primeiro_elemento);

	if (strcmp (primeiro_elemento, "N")==0) {						/*Identifica as linhas que ordenam a criação de um objecto*/
		i = 0;
		erro = 0;
		fgets (comandos, 200, fp);

		if(sscanf (comandos, "%s %d %d %s", nome, &vertices, &cor, verificacao)!=3) {	/*Verifica se a linha de atribuição de nome, vértice e cor tem três elementos. Se não utilizássemos a variável verificacao ele não detectaria se a linha tinha mais elementos do que o suposto*/
			printf ("\t**** A linha de atribuição de nome, vértice e cor\n\t  do %dº objecto tem parâmetros incorrectos ****\n\n",Comando_criacao + 1);
		}	

		else {
			if (vertices <= 0){						/*O número de vértices tem que ser positivo*/
				printf ("\t**** O %dº objecto tem o número de vértices inválido ****\n\n",Comando_criacao + 1);
			}
			else {
				if ( cor < -26 || cor > 26){					/* O número correspondente à cor situa-se entre -26 e 26 */
					printf ("\t**** Atribuição errada da cor do %dº objecto ****\n\n",Comando_criacao + 1);

                                        }else {		
					Comando_criacao = Comando_criacao +1;			/*Só contabiliza a criação do objecto se nenhum dos erros em cima for detectado, pois esta estrutura está encadeada nas anteriores*/	
				}	
			}	
		}

		while (i < vertices){			/*Ciclo de verificação das coordenadas dos vértices*/

			coordenada_x=coordenada_y=100000000;
			fgets (comandos, 200, fp);
			if (sscanf (comandos, "%d %d %s", &coordenada_x, &coordenada_y, verificacao)!=2){	/*Verifica se a linha tem 2 elementos.*/			
				erro = erro +1;
				i = i+1;
			}
			else {
				if (coordenada_x==100000000 && coordenada_y==100000000){		/*Mesmo que a linha tenha dois elementos é necessário verificar se são válidos, ou seja, se são valores numéricos.*/
					erro = erro + 1;
				}
				else {
					i=i+1;			/*Contabiliza o número de linhas lidas neste ciclo*/
			}	}

		}
		if (erro!=0){
			printf ("\t ****O %dº objecto tem coordenadas inválidas ****\n\n", Comando_criacao + 1);
			Comando_criacao = Comando_criacao  - 1;					/*Descontao objecto incorrectamente criado.*/

ah e outra coisa....como podia fazer de maneira a que o numero de vertices seja igual ao numero de coordenadas...do tipo:

vertices:

4

coordenadas:

50 100

100 100

50 50

100 50

obrigado

cumprimentos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O fgets() mantem o ENTER na string.

A comparação com "N" nunca pode dar igual. Podes comparar com "N\n", mas acho melhor comparar só o primeiro caracter com o caracter 'N'.

Acho que tens fgets() a mais no teu programa (mas sem saber a estrututa dos dados, é um acho muito fraquito).

Sem saber a estrutura dos teus dados é difícil dar sugestões.

Mete lá aqui um bocadinho da estrutura dos dados (linhas com N, linhas com N e mais qualquer coisa, linhas a seguir ao N quer tenham N, ou outra letra, ou nada, ...).

De qualquer maneira, separa o teu código em diferentes funções. Não ponhas tudo junto no mesmo bloco.

Por exemplo

while (fgets (comandos, 200, fp)!=NULL){                        /*Percorre o ficheiro até ao fim*/
  switch(comandos[0]) {
    case 'T': do_the_T_thing(); break;
    case 'P': do_the_P_thing(); break;
    case 'N': do_the_N_thing(); break;
    case 'S': do_the_S_thing(); break;
    case 'C': do_the_C_thing(); break;
    case 'E': do_the_E_thing(); break;
    case 'R': do_the_R_thing(); break;
    default: erro(); break;
  }
} /*while*/

É claro que tens de definir as funções do_the_X_thing()

como podia fazer de maneira a que o numero de vertices seja igual ao numero de coordenadas

Lês o número de elementos e crias um array com esse tamanho :)

elements = 4;
array = malloc(elements * sizeof *array);
if (array) {
    /* trata o array */
    /* ... */
    /* por exemplo */
    int soma = 0;
    for (k=0; k<elements; k++) {
        soma += array[k];
    }
    /* ... */
    /* e liberta a memória quando já não for necessária */
    free(array);
} else {
    /* falta de memória */
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mas este programa nao posso ler o numero de vertices que tem porque pode ter n vertices

cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mas este programa nao posso ler o numero de vertices que tem porque pode ter n vertices

Então vais aumentando o array à medida que vais lendo vertices:

size_t vertices = 0;
struct Vertice vertice;
struct Vertice *array = NULL;
while (read_vertice(&vertice)) {
   /* error checking omitido -- ********** MAS DEVIA CÁ ESTAR ******** */
   realloc(array, (1 + vertices) * sizeof *array);
   array[vertices++] = vertice;
}
/* usa array aqui */
/* e liberta memória quando já não for necessária */
free(array);

O realloc é uma operação pesada. Se o teu programa ficar muito lento, podes fazer alocações incrementais à medida do necessário. É claro que tens de programar mais para ter tudo sob controle, mas, dependendo dos teus dados e aplicação, é uma coisa a ter em conta.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

boas,

disseram-me que apartir do strlen da para definir o tamanho do caracter a ser lido?

alguem me sabe dizer como?

queria fazer isso para os caractares...para ele ler so o caracter e mais nada

cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

disseram-me que apartir do strlen da para definir o tamanho do caracter a ser lido?

tamanho do carácter? queres dizer tamanho da string?

para leres uma string com n caracteres podes fazer:

scanf("%n[^\n]", str);

onde alteras o primeiro n da linha anterior para o numero de caracteres que queres ler

mas se queres so ler 1 carácter porque nao usar o getchar() ?

o strlen devolve o numeros de caracteres de uma string (excluindo o carácter terminador)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

LOL

é o projecto de programação do técnico xD também estou a fazer

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora