Ir para conteúdo

Arquivado

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

Beraldo

Alocar dinamicamente memória para uma string

Recommended Posts

Há alguns dais comecei a estudar alocação dinâmica em C.

 

Quero armazenar numa variável uma string fornecida pelo usuário, mas não quero solicitar, a priori, o tamanho da string, a fim de realizar a alocação. A solução que imaginei foi alocar 10 bytes, depois alocar mais 10, se necessário, e assim por diante.

 

Tentei fazer assim:

#include <stdio.h>
#include <malloc.h>
#include <string.h>


int main()
{
	char *str;
	
	str = (char *) malloc(10 * sizeof(char));
	
	printf("Digite a string: ");
	
	while (fgets(str, 10, stdin) != NULL)
	{
		str = (char *) realloc(str, strlen(str) + 10 * sizeof(char));
	}
	
	printf("%s\n\n", str);
	
	free(str);
	
	return 0;
}
Mas o programa não se encerra. :unsure:

 

 

Os exemplos que encontro na Internet sempre solicitam ao usuário o tamanho da string, para fazer a alocação do tamanho certo. Não quero fazer assim.

Como pode ser uma solução?

 

[]s

Beraldo

Compartilhar este post


Link para o post
Compartilhar em outros sites

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.

 

Não pára porque EOF não brota do nada. você tem que sinalizar EOF...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Deve haver melhores formas de fazer, mas voce pode ler uma string já limitando a entrada com fgets e depois calcular o tamanho da string.

Faça a alocação e copie o conteúdo de uma string para outra.

Pode fazer a alocação char a char, mas não sei se é melhor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.

 

Não pára porque EOF não brota do nada. você tem que sinalizar EOF...

Eu já tinha lido isso. Tenho todos os pacotes das manpages instalados aqui.

É que eu pensei que a leitura pararia (considerando-se EOF) quando a string finalizasse.

 

Como seria essa sinalização a que você se refere?

 

 

 

Deve haver melhores formas de fazer, mas voce pode ler uma string já limitando a entrada com fgets e depois calcular o tamanho da string.

Faça a alocação e copie o conteúdo de uma string para outra.

Pode fazer a alocação char a char, mas não sei se é melhor.

Limitar com fgets() não seria como eu fiz? Não entendi direito sua colocação.

Acho que alocar char a char não é muito eficiente, pois, segundo meus professores, malloc() gasta muito tempo de execução (ainda não o teste prártico), sendo mais conveniente alocar mais a cada vez (como 10 a 10), mesmo que sobre um pouco de memória alocada na string.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ctrl + D no Unix e Ctrl + z no Windows.

 

 

Um detalhe é que o conteúdo vai se perdendo.

Voce tem que arrumar alguma forma de armazenar esse conteúdo digitado.

Por isso minha primeira sugestão de ler tudo de uma vez e depois calcular o tamanho.

Compartilhar este post


Link para o post
Compartilhar em outros sites

CTRL + D não resolve da maneira como quero, pois desejo que a leitura termine no fim da string, sem que seja necessário inserir algo mais, de forma que eu possa usar a técnica para armazenar espaço para strings vindas de arquivos ou do SO.

 

 

Consegui o que eu queria com este código:

 

#include <stdio.h>
#include <malloc.h>
#include <string.h>

int main()
{
	char c, *str = NULL;
	int i = 0, j = 1;
	
	str = (char *) malloc(10 * sizeof(char) + 1);
	
	printf("Digite a string: ");
	
	while ((c = getchar()) != '\n' && c != EOF && c != '\0')
	{
		if (j == 10)
		{
			str = (char *) realloc(str, strlen(str) + 10 * sizeof(char) + 1);
			j = 1;
		}
		*(str + i * sizeof(char)) = c;
		i++;
		j++;
	}
	
	*(str + i * sizeof(char)) = '\0';
	
	puts("\n\n");
	
	printf("%s\n\n", str);
	
	free(str);
	
	return 0;
}

Obrigado! :D

 

[]s

Beraldo

Compartilhar este post


Link para o post
Compartilhar em outros sites

É nessas horas que eu agradeço a existência do getline.

 

getline() reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character, if one was found. If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should be freed by the user program. Alternatively, before calling getline(), *lineptr can contain a pointer to a malloc()-allocated buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc(), updating *lineptr and *n as necessary. In either case, on a successful call, *lineptr and *n will be updated to reflect the buffer address and allocated size respectively.

 

Both getline() and getdelim() are GNU extensions. They are available since libc 4.6.27.

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.