Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

paulopatto

Caracter nulo, termino de string

Recommended Posts

Olá bom dia.

 

 

Tenho o seguinte código:

 

 

/**
 * ANSI C Standart Code with library standart ANSI (STD)
 * @author Paulo Patto
 */
#include<stdio.h>
#define LENGTH 3


typedef struct{
	int id;
	char nome[30];
	float celsius;
	float fahrenheit;
}Registro;

float toFahrenheit(float celsius){return (celsius * 1.8) + 32;}

void gravar(Registro r[]){
	FILE* file = fopen("bancoDeDados.dat","w");
	
	fprintf(file,"[CELSIUS];[FAHRENHEIT];[CIDADE];\n");
	for(int c = 0; c < LENGTH; c++){fprintf(file,"%0.2f;%0.2f;%s\n", r[c].celsius,r[c].fahrenheit, r[c].nome);}
}

int main(){
	
	int i = 0;
	Registro registros[LENGTH];
	
	printf("\t...:::CADASTRO DE TEPERATURAS:::...\n");
	
	for(i = 0; i < LENGTH; i++){
		printf("Entre com o nome da cidade: ");
		fgets(registros[i].nome, 30, stdin);
		fflush(stdin); //Limpar o Buffer do dispositivo de entrada padrão, em nosso caso o teclado.
		
		printf("Entre com a temperatura em graus Celsius: ");
		scanf("%f",&registros[i].celsius);
		fflush(stdin); //Limpar o Buffer do dispositivo de entrada padrão, em nosso caso o teclado.
		registros[i].fahrenheit = toFahrenheit(registros[i].celsius);
		
		printf("\n");
	}
	
	printf("Garavando no Banco de dados...\n");
	gravar(registros);
	printf("Registros gravados com sucesso.\n");
	getchar();

}

 

Só que gravado a string no arquivo de texto eu encontro problema de que ele pula de linha automaticamente, ou seja só de encontrar o terminado de string. Existe alguma forma de contronar esse comportamento?

 

Desde já agradeço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

faça tipo um:

palavra[strlen(palavra)-1] = '\0';

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

como assim o barra zero soh indica o final da string ele num vai aparecer na gravação;

 

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

você está usando qual compilador / ide?

 

no Code::Blocks, em modo debugger, você pode abrir o painel "watches" e ver as variáveis locais e globais em tempo de execução!

ai você poderá ver que toda string em C contém um '\0' no final!

 

ex:

char mString1[]="Olá, essa é minha string";

 

uma string declarada assim, na memória fica:

"Olá, essa é minha string\0"

 

 

 

Obs.:

Cara, eu vi um fflush(stdin); ai no seu código, não posso deixar de comentar...

 

não use fflush para streams de entrada!!!!!

Porque?

Na documentação da função está escrito:

"Effect undefined for input stream"

 

http://www.utas.edu.au/infosys/info/docume...Lib.html#fflush

 

Existem outras maneiras mais elegantes, e corretas de limpar o buffer do teclado!

uma delas é limpar ele na hora que o usuário digita, colocando um token: "%*c" no final do scanf.

 

isso diz para o scanf ler e DESCARTAR o ultimo caractere, que será um '\n' do "enter" que o usuário digitou.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas o '\0' fica só na memória né? Não faz parte da string realmente, é usado apenas para sinalizar o fim da string.

Esse problema de pular a linha é porque o fgets() adiciona SEMPRE no final da string um \n. quit acredito que tenha que pegar os dois últimos caracteres porque o \n faz parte da string e ainda tem o '\0' pra sinalizar o fim dela, me corrijam se eu estiver errado :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas o '\0' fica só na memória né? Não faz parte da string realmente, é usado apenas para sinalizar o fim da string.

Quase isso....

 

toda a string está na memória...

por exemplo:

 

char teste[20];

//nossa string teste é algo do tipo: ******************** , pois ainda não foi inicializada.

strcpy(teste, "1234567890");

//agora, teste é: 1234567890\0*********

strcat(teste, "aa");

//agora teste é: 1234567890aa\0*******

Logo, não é aconselhável fazermos:

char teste[2];

strcpy(teste, "aa");

pois não terá espaço para o caractere nulo ('\0' é um caractere nulo, na tabela ASCII, 0 corresponde a NULL).

O comportamento seria indefinido.

pode funcionar, como não pode...

Compartilhar este post


Link para o post
Compartilhar em outros sites

você está usando qual compilador / ide?

 

no Code::Blocks, em modo debugger, você pode abrir o painel "watches" e ver as variáveis locais e globais em tempo de execução!

ai você poderá ver que toda string em C contém um '\0' no final!

 

ex:

char mString1[]="Olá, essa é minha string";

 

uma string declarada assim, na memória fica:

"Olá, essa é minha string\0"

 

 

 

Obs.:

Cara, eu vi um fflush(stdin); ai no seu código, não posso deixar de comentar...

 

não use fflush para streams de entrada!!!!!

Porque?

Na documentação da função está escrito:

"Effect undefined for input stream"

 

http://www.utas.edu.au/infosys/info/docume...Lib.html#fflush

 

Existem outras maneiras mais elegantes, e corretas de limpar o buffer do teclado!

uma delas é limpar ele na hora que o usuário digita, colocando um token: "%*c" no final do scanf.

 

isso diz para o scanf ler e DESCARTAR o ultimo caractere, que será um '\n' do "enter" que o usuário digitou.

 

Bem eu uso o Bloodshed Dev C++ 4.9.9.2.

O fflush(stdin) foi usado pois ao ler strings com a função scanf(), gets() e fgets() o buffer enchia a proxima leitura ou outras variaeis com lixo. Se puder me dar um exemplo de uso com %*c eu agradeço, porem eu vou precisar ler strings com espaços.

Mas mesmo asssim muiito obrigado pelas dicas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas o '\0' fica só na memória né? Não faz parte da string realmente, é usado apenas para sinalizar o fim da string.

Quase isso....

 

toda a string está na memória...

por exemplo:

 

char teste[20];

//nossa string teste é algo do tipo: ******************** , pois ainda não foi inicializada.

strcpy(teste, "1234567890");

//agora, teste é: 1234567890\0*********

strcat(teste, "aa");

//agora teste é: 1234567890aa\0*******

Logo, não é aconselhável fazermos:

char teste[2];

strcpy(teste, "aa");

pois não terá espaço para o caractere nulo ('\0' é um caractere nulo, na tabela ASCII, 0 corresponde a NULL).

O comportamento seria indefinido.

pode funcionar, como não pode...

 

 

Muito feliz esse exemplo de como strings são armazenadas na memória, isso agente pode observar pelo DEBUG do Dev C++.

 

Mas sobre o comentário de que o fgets sempre coloca um \n, olha sinceramente nunca vi nada a respeito disso e outra já vi pessoas usando fgets e não tendo o break line.

 

Bem eu venho pegando minhas referencias em www.cplusplus.com, só acho estranho que um mesmo código fonte com o mesmo compilador e SO porem em PCs diferente em um apresenta um comportamento e em outro não um exemplo é esse com a função SCANF e FGETS onde em um não fica lixo no buffer em outro eu tenho que limpar com fflush(stdin).

 

 

Em todo caso vossas sugestões são sempre muito bem vindas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

como assim o barra zero soh indica o final da string ele num vai aparecer na gravação;

 

[]s

Bem na teoria é assim, já na prática não é o que vem se mostrando, a não ser que como abaixo citado seja adicionado ainda mais um \n que eu não ví no debug de meu IDE.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Poderia postar um código onde o fgets() não coloca um \n no final? E como o Victor falou não use fflush para limpar streams de entrada pois o mesmo tem comportamento indefinido.

 

O exemplo:

char nome[60];
printf("Digite seu nome:");
scanf("%[^\n]%*c,nome) //vai ler a entrada até encontrar um break line e fazer o que o Victor disse...

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.