Ir ao conteúdo

Posts recomendados

Postado

Para gerar o tabuleiro de um jogo, preciso ler um arquivo que contém posições dos monstros, das armadilhas, do chefe e do personagem principal. O arquivo segue este formato (sem os comentários):

//1o linha do arquivo: posição do herói
1C
//o 2a linha do arquivo: posições dos monstros
1B 2D 3F 4H
//o 3 a linha do arquivo: quantidade de armadilhas
5
//o 4 a linha do arquivo: posições das armadilhas
2A 2E 3J 4C 5G
//o 5a linha do arquivo: posição do Chefão
5J

O código é o seguinte:
 

void debug(criatura personagem){
	int arg = 1;
	
	FILE *arquivo;
	criatura inimigo;
	criatura chefe;
	criatura armadilha;
	criatura tabuleiro[5][10];
	armadilha.classe = 'x';
	inimigo.classe = 'i';
	chefe.classe = 'C';
	char nome[100];
	char txt[5] = ".txt";
	char ph[2];
	char monstro[500];
	char arm[500];
	int col,lin,i,narm;
	
	system("cls");
	printf("\n\t\t-- MODO DEBUG --\n   Digite o nome do arquivo que deseja abrir:\n   >> ");
	scanf(" %s",nome);
	i = strlen(nome);
	if(nome[i-1]!='t'){
		strcat(nome,txt);
	}
	
	arquivo = fopen(nome,"r");
	
	if(arquivo==NULL){
		perror("Arquivo nao encontrado! =(\n");
		exit(-1);
	}else{	
		fscanf(arquivo,"%s",&ph);
		printf("%s",&ph);
		system("pause");
		lin = convertlin(ph);
		col = convertcol(ph);
		tabuleiro[lin][col].classe = personagem.classe;
		fgets(monstro,sizeof(monstro),arquivo);
		
		while(monstro[i]!='\n'){
			lin = convertlinM(monstro);
			col = convertcolM(monstro);
			tabuleiro[lin][col].classe = inimigo.classe;
			puts(monstro);
			i++;
		}
		
		system("pause");	
		fscanf(arquivo,"%d",&narm);
		printf("%d",narm);	
		for(i=0;i<narm;i++){
			fscanf(arquivo,"%s",&arm);
			lin = convertlinM(arm);
			col = convertcolM(arm);
			tabuleiro[lin][col].classe = armadilha.classe;
		}
		printf("%s",&arm);
		system("pause");
		fscanf(arquivo,"%s",&ph); // PH AQUI USADO COMO CHEFE
		printf("%s",&ph);
		system("pause");
		lin = convertlin(ph);
		col = convertcol(ph);
		tabuleiro[lin][col].classe = chefe.classe;
	}
	fclose(arquivo); 
}

apresenta problemas logo após ler a posição do herói. 

Os printf são meramente para eu saber como anda a leitura, serão retirados depois. As funções convertlin e convertcol simplesmente pegam o valor recebido e retornam algo que eu possa utilizar na tabela.

 

Eu tinha feito algumas variações achando q poderiam resolver:

-> imprime 5J infinitamente

while(fscanf(arquivo,"%s",&monstro)!='\n'){
            lin = convertlinM(monstro);
            col = convertcolM(monstro);
            tabuleiro[lin][col].classe = inimigo.classe;
            puts(monstro);
        }

->  Esta acaba imprimindo tudo até o final, em vez de pegar apenas a linha dos monstros:

for(i=0;i!='\n';i++){
            fscanf(arquivo,"%s",&monstro);
            lin = convertlinM(monstro);
            col = convertcolM(monstro);
            tabuleiro[lin][col].classe = inimigo.classe;
            puts(monstro);
        }

Se alguém souber me explicar como fazer essa leitura, ficarei MUITO grato 

[]'s

  • Curtir 2
Postado

@sN4ke Uma pergunta, como você sabe que essas linhas:

while(monstro[i]!='\n'){
			lin = convertlinM(monstro);
			col = convertcolM(monstro);
			tabuleiro[lin][col].classe = inimigo.classe;
			puts(monstro);
			i++;
		}

 

estão funcionando logicamente?

 

Já que você sempre envia a string monstro para converter mas não identifica o índice, então já invalida o resto do código.

O correto seria:

i = 0;
puts(monstro);
while(monstro[i]!='\n' || strlen(monstro) < i){
			lin = convertlinM(monstro[i]);
			col = convertcolM(monstro[i+1]);
			tabuleiro[lin][col].classe = inimigo.classe;
			i+=2;//pula linha em branco
}

 

Você também sempre vai imprimir a string monstro usando puts(monstro), use fora do loop, ou use putc.

 

 

 

  • Curtir 2
Postado

@TYSQUARE89 obrigado por responder!
Por algum motivo, o programa não está imprimindo a string monstro, creio que isso seja indicativo de algum erro. Além disso, não sei se chega a ser realmente um problema, mas apesar de compilar, o Dev acusa como erro a passagem de uma posição da string por valor. Estou pensando aqui e talvez as funções que fazem as conversões das linhas não estejam adequadas. De qualquer forma, o programa apresenta problemas logo quando deveria entrar no while. Segue um print:

@edit o problema ao qual me refiro é de crashar mesmo

- edit 2: resolvi o problema da linha em branco. 

Faltava um espaço nesse scanf:

fscanf(arquivo,"%s",&ph);

O correto é:

fscanf(arquivo,"%s ",&ph);

Não entendo muito bem porque resolve, apenas vi um gringo recomendando isso aqui:
https://stackoverflow.com/questions/17568649/using-fgets-to-get-a-line-in-c

[]'s

 

erros.png

  • Curtir 1
Postado

@sN4ke Tente usar a função converlinM apenas para receber um char. Usando esse código que postei acima você apenas precisa filtrar/retornar o valor da linha e coluna, ex:

//na leitura use:
i = 0;
puts(monstro);
while(monstro[i]!='\n' || strlen(monstro) < i){
			lin = (int)monstro[i]-48;                           //'2'C < pega o 2 - se o 1º for maior que 9 ele buga...
			col = convertcolM(monstro[i+1]);                    //filtra coluna, já que é letra
			tabuleiro[lin][col].classe = inimigo.classe;
			i+=2;                                               //pula linha em branco - 2C<pula>2B
}
              
//na função de retornar a coluna - ALTERE OS CASES DO SEU JEITO            
int convertcolM(char c){
    int saida = -1;
  
	switch(c){    
        case 'A': saida = 1; break;	//coluna A retorna 1
        case 'B': saida = 2; break;	//coluna B retorna 2	
        case 'C': saida = 3; break;	//coluna C retorna 3...	
              
        //nao encontrado
        default:
        break;
    }
    //saida < 0 se não encontrou a COL do monstro 
	return saida;
}

 

  • Curtir 1
Postado

@TYSQUARE89 Na primeira vez do loop o programa parece estar obtendo a linha e a coluna corretamente, porém na segunda a linha já torna-se um valor bizarro (-16). 

Imprimi até onde ele chegou, a linha e a coluna já convertidos para sabermos o que tá rolando

Aliás, aqui não deveria chamar uma função?

lin = (int)monstro[i]-48;

alright.png

 

Novamente, obrigado pela ajuda!

 

@TYSQUARE89 Fiz  algumas edições e agora o programa vai até um pouquinho mais longe. Como não compreendi bem aquele -48, acabei retornando pro meu código e reaproveitando coisas que você fez.

Código atualizado:

void debug(criatura personagem){
	int arg = 1;
	
	FILE *arquivo;
	criatura inimigo;
	criatura chefe;
	criatura armadilha;
	criatura tabuleiro[5][10];
	armadilha.classe = 'x';
	inimigo.classe = 'i';
	chefe.classe = 'C';
	char nome[100];
	char txt[5] = ".txt";
	char ph[2];
	char monstro[500];
	char arm[500];
	int col,lin,i,narm,nmon;
	
	system("cls");
	printf("\n\t\t-- MODO DEBUG --\n   Digite o nome do arquivo que deseja abrir:\n   >> ");
	scanf(" %s",nome);
	i = strlen(nome);
	if(nome[i-1]!='t'){
		strcat(nome,txt);
	}
	
	arquivo = fopen(nome,"r");
	
	if(arquivo==NULL){
		perror("Arquivo nao encontrado! =(\n");
        exit(-1);
	}else{
		while(!feof(arquivo)){
			fscanf(arquivo,"%s ",&ph);
			lin = convertlin(ph);
			col = convertcol(ph);
			tabuleiro[lin][col].classe = personagem.classe;
			printf("%s ",&ph);
			fflush(stdin);
			system("pause");
			fgets(monstro,500,arquivo);
			fflush(stdin);
			puts(monstro);
			system("pause");
			fscanf(arquivo,"%d ",&nmon);
			i = 0;
			while(monstro[i]!='\n' || strlen(monstro) < i){
				lin = convertlinM(monstro[i]);
				col = convertcolM(monstro[i+1]);
				tabuleiro[lin][col].classe = inimigo.classe;
				printf("linha:%d - coluna: %d - classe: %c",lin,col,tabuleiro[lin][col].classe);
				system("pause");
				i+=3;//pula linha em branco
			}
		}
	}
	
	fclose(arquivo); 
}

int convertcolM(char c){
    int saida = -1;
  
	switch(c){    
        case 'A': saida = 0; break;	//coluna A retorna 0
        case 'B': saida = 1; break;	//coluna B retorna 1	
        case 'C': saida = 2; break;	//coluna C retorna 2...	
        case 'D': saida = 3; break;
        case 'E': saida = 4; break;
        case 'F': saida = 5; break;
        case 'G': saida = 6; break;
        case 'H': saida = 7; break;
        case 'I': saida = 8; break;
        case 'J': saida = 9; break;  
              
        //nao encontrado
        default:
        break;
    }
    //saida < 0 se não encontrou a COL do monstro 
	return saida;
}

int convertlinM(char c){
	int saida=-1,i;
	
	switch(c){
		case '1': saida = 0; break;
		case '2': saida = 1; break;
		case '3': saida = 2; break;
		case '4': saida = 3; break;
		case '5': saida = 4; break;
	}
	return saida;
}


 

O problema agora parece ser na hora de sair do looping:

 

 

update.png

Postado

@sN4ke Esse código: (int)monstro-48 só serve de 0 a 9, então antes do switch(c) verifique com um printf a letra e decimal do argumento c, para saber quais letras estão sendo usadas.

Em (int)monstro, troque por:

lin = (int)(monstro[i]-48);

Questão de prioridade.

Postado
19 minutos atrás, TYSQUARE89 disse:

@sN4ke Esse código: (int)monstro-48 só serve de 0 a 9, então antes do switch(c) verifique com um printf a letra e decimal do argumento c, para saber quais letras estão sendo usadas.

Em (int)monstro, troque por:


lin = (int)(monstro[i]-48);

Questão de prioridade.

 

Certo, fiz a troca e parece estar funcionando bem, o problema agora parece ser na hora de sair do loop. Aparentemente ele não está identificando um '\n' ou o strlen e começa a pegar lixo...

Aliás o professor disse que eu poderia adicionar a quantidade de monstros para facilitar, assim:
 

Citação

 

1C

4 // número de monstros
1B 2D 3F 4H
5
2A 2E 3J 4C 5G
5J

 

 

Tentarei colocar esse número como condição pro while de alguma forma

Postado

@TYSQUARE89 acho que tá quaaaseee lá, mas ainda tem algo apresentando problemas pra pegar os dados finais. É bizarro, porque para ver as posições das armadilhas eu basicamente tenho que fazer o mesmo que fiz para ler a posição dos monstros. Da mesma forma, para pegar a posição do chefe, o procedimento parece ser igual ao que eu fiz para pegar a posição do herói. No entanto, mesmo tentando seguir a mesma lógica, o programa apresenta problemas ao sair do for do número de armadilhas (narm). Eu já devo estar enchendo teu saco, mas se souber me dizer o que fiz de errado dessa vez, vai me ajudar bastante mesmo!

 

			//while(!feof(arquivo)){  <- Removi isso porque não tem necessidade, já que eu percorro o código "manualmente"...
			fscanf(arquivo,"%s ",&ph);
			lin = convertlin(ph);
			col = convertcol(ph);
			tabuleiro[lin][col].classe = personagem.classe;
			printf("%s ",&ph);
			fscanf(arquivo,"%d ",&nmon);
			fgets(monstro,500,arquivo);
			puts(monstro);
			system("pause");
			i = 0;
			for(m=0;m<nmon;m++){
				lin = (int)(monstro[i]-48);
				col = convertcolM(monstro[i+1]);
				tabuleiro[lin][col].classe = inimigo.classe;
				printf("linha:%d - coluna: %d - classe: %c",lin,col,tabuleiro[lin][col].classe);
				system("pause");
				i+=3;//pula linha em branco
			}
			fscanf(arquivo,"%d ",&narm);
			fgets(arm,500,arquivo);
			puts(arm);
			i=0;
			for(m=0;m<narm;m++){
				lin = (int)(arm[i]-48);
				col = convertcolM(arm[i+1]);
				tabuleiro[lin][col].classe = armadilhaP.classe;
				printf("linha:%d - coluna: %d - classe: %c",lin,col,tabuleiro[lin][col].classe);
				system("pause");
				i+=3;
			}
				fscanf(arquivo,"%s ",&ph);
				lin = convertlin(ph);
				col = convertcol(ph);
				tabuleiro[lin][col].classe = chefe.classe;
				printf("%s ",&ph);*/
	}

	fclose(arquivo); 

Sem esse segundo for o arquivo inclusive fecha bonitinho, porém aí eu fico sem as posições das armadilhas e do chefe...

edit:

Esse print deve ajudar com informações extras. Percebi q ele tá pegando números errados pra posição do chefe, mas não sei se isso seria motivo pra crashar...

errofinal.png

  • Curtir 1
Postado

@sN4ke Não se preocupe em incomodar, estou aqui voluntariamente, porém demoro um pouco para responder :S, enfim...

Você sabe se essas linhas:

fscanf(arquivo,"%d ",&narm);

fgets(arm,500,arquivo);

 

estão recebendo corretamente a quantidade e as armadilhas?...

  • Curtir 1
Postado
2 minutos atrás, TYSQUARE89 disse:

@sN4ke Não se preocupe em incomodar, estou aqui voluntariamente, porém demoro um pouco para responder :S, enfim...

Você sabe se essas linhas:

fscanf(arquivo,"%d ",&narm);

fgets(arm,500,arquivo);

 

estão recebendo corretamente a quantidade e as armadilhas?...

Acabei de testar e sim! 
O printf para o narm mostra 5 e o puts para o arm mostra as armadilhas exatamente como estão no .txt

Postado
4 minutos atrás, TYSQUARE89 disse:

Oke, eu acredito que seja melhor usa o fscanf assim:

char ch[2];

fscanf(arquivo,"%s", ch);

 

Cheguei a trocar, infelizmente ainda não é isso =/

Postado

@TYSQUARE89 AEEEEHOOOO, finalmente está pronto!!! Obrigadão, cara! Eu removi esse & aí (que vacilo) e refiz as funções convertlin e convertcol usando o modelo de switch que você tinha passado anteriormente. Tudo rodando! =D

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...