Ir ao conteúdo

Posts recomendados

Postado

Qual o motivo da utilização do sizeof dentro do fgets nesse exemplo? Sei que ele retorna bytes e que o fgets precisa de um parâmetro de dimensão --> exemplo 50 como máximo de que pode ser armazenado em uma string.

#include <stdio.h>

#define max 10

int main()
{
	char palavra[max];
	int i, j;
	FILE *arq;
	//cria e vincula o arquivo a uma variavel
	char *arq = "texto.txt";
	//abre o arquivo com especificação w : somente escrever 
	arq = fopen ("texto.txt", "w"); 
	//necessário para casos de erros externos
	if (arq == NULL)
		printf ("Arquivo não aberto. Erro\n");
	else
	{
		/*OBS: não será armazenado todas as informações   na  váriavel,
		 mas sim,será usada como um tipo de onibus de strings, ou seja,
		 ela armazena e joga no arquivo*/
		for (i=0; i<max; i++){
			printf("Digite a %dª palavra: ", i+1);
			scanf("%s", palavra);
			fflush(stdin);
		//função que escreve e pula um linha no arquivo do HD
			fprintf(arq, "%s\n", palavra);
		}
	}
	fclose(arq);
//abre o arquivo novamente, porém no modo leitura "r"	
	arq = fopen ("texto.txt", "r");
	if (arq == NULL)
		printf ("\nArquivo não aberto. Erro\n");
	else
//le o arquivo e printa na tela linha por linha != null
//não sei pra que funciona o sizeof (nesse exemplo)
	{
		while((fgets(palavra, sizeof(palavra), arq))!=NULL )
			printf("%s\n", palavra);
	}
	fclose(arq);
	return (0);
}

 

  • Curtir 1
Postado

 

fgets(palavra, sizeof(palavra), arq)

Na verdade há um bug em potencial acima. A documentação de fgets diz que o segundo parâmetro deve ser o numero máximo de caracteres a serem lidos de arq e armazenados no local apontado por palavra. Ou seja, seria mais correto usar o seguinte:

 

fgets(palavra, max, arq)

 

O código ainda funciona porque você alocou o vetor palavra estaticamente com 10 elementos e caso, por exemplo, um char na sua maquina equivalha a 8 bits, o resultado de sizeof seria 10x8 = 80 bits. fgets então assume que deve ler ate 80 caracteres e não 10. Ela vai parar de ler na primeira ocorrência de uma das três possibilidades a seguir: a) leu 79 caracteres; b) leu o marcador de uma nova linha '\n'; ou, c) chegou ao final do arquivo apontado por arq.

 

Um bug ainda mais feio poderia ocorrer se palavra tivesse sido alocada dinamicamente:

 

char *palavra = malloc(sizeof(char)*max);

 

O resultado de sizeof nesse caso seria apenas os 8 bits do tipo char em paralavra[0].

 

Uma boa pratica seria não usar sizeof pra determinar numero de elementos, apenas numero de bits. Principalmente quando os vetores em questão são alocados estaticamente. Caso mais tarde o mesmo vetor venha a ser alocado dinamicamente, é muito provável que vários bugs, por vezes difíceis de resolver, apareçam. Principalmente se o projeto é grande (vários arquivos fontes, milhares de linhas de código etc).

 

 

  • Curtir 1
  • Obrigado 2
  • Triste 1
Postado
{
	while((fgets(palavra, sizeof(palavra), arq))!=NULL )
	    printf("%s\n", palavra);
}

Porque não tentou ao menos rodar um programa assim?

#define max 10
#include <stdio.h>
int main(int argc, char** argv)
{   char palavra[max];
    printf("sizeof(palavra[max]) %d max %d sizeof(char) %d\n",
        sizeof(palavra), max, sizeof(char));
    return 0;
};

 

Não, não há um bug. Esse é o modo comum de chamar gets()


Eis o protótipo

	char *fgets(char *str, int n, FILE *stream)

Curiosamente aceita um int ao invés de um const unsigned mas é isso.

 

Aqui sim temos um bug:
 

8 horas atrás, V!OLADOR disse:

Na verdade há um bug em potencial acima. A documentação de fgets diz que o segundo parâmetro deve ser o numero máximo de caracteres a serem lidos de arq e armazenados no local apontado por palavra. Ou seja, seria mais correto usar o seguinte:

 


fgets(palavra, max, arq)

 

Como vê no "programa" acima, max é 10 e palavra tem 30 bytes então fgets() não vai deixar você ler além de 10...

 

Cuidado com essas definições.

 

Se usar alocação dinâmica não há no padrão como identificar o tamanho da área alocada, um sizeof(). E isso não deveria ser um problema: se foi você que alocou passou o tamanho no malloc() então você deve saber. Se não foi você deve haver uma documentação dizendo até onde pode ler. 
 

2 horas atrás, Flávio Pedroza disse:

O operador sizeof retornar o número de BYTES, não de bits

 

Exato
 

7 horas atrás, AnonymousLPH disse:

Estava pensando nisso também, esse exemplo me chegou assim, logo sai pesquisando e fiquei planando, agora que tu amarrou uma pedra no meu pé, eu posso voltar a dar meu difíceis passos, obgd

 

Na dúvida, recorte o trecho de código e teste em separado. Leva minutos.

 

8 horas atrás, V!OLADOR disse:

O resultado de sizeof nesse caso seria apenas os 8 bits do tipo char em paralavra[0].

 

Uma boa pratica seria não usar sizeof pra determinar numero de elementos, apenas numero de bits. Principalmente quando os vetores em questão são alocados estaticamente

 

Cuidado. Isso não faz sentido. E não seria boa prática. E a observação não se aplica: sizeof() nada tem a ver com vetores. Apenas tipos ou variáveis estaticamente alocadas.

 

Citação

sizeof() é um operador e não uma função. 

 

Não deve confiar: LEIA e rode esse programa

#define max 10
#include <stdio.h>
int main(int argc, char** argv)
{
    char palavra[max];
    printf("sizeof(palavra[max]) %d max %d sizeof(char) %d\n",
        sizeof(palavra), max, sizeof(char));
    printf("sizeof's (char) %d (int) %d (long) %d\n",
        sizeof(char), sizeof(int), sizeof(long));
    printf("sizeof's (long long) %d (double) %d (float) %d\n",
        sizeof(long long), sizeof(double), sizeof(float));
    printf("sizeof's (palavra[0]) %d\n(32 bits)\n",
        sizeof(palavra[0]));
    return 0;
};

E verá

sizeof(palavra[max]) 10 max 10 sizeof(char) 1
sizeof's (char) 1 (int) 4 (long) 4
sizeof's (long long) 8 (double) 8 (float) 4
sizeof's (palavra) 1
(32 bits)

Como vê, por ser um operador, você pode chamar sizeof() com tipos também.

sizeof na documentação

 

Citação

sizeof() de uma struct retorna um valor que incorpora o total de bytes ocupados pela estrutura e isso inclui possíveis bytes inseridos para alinhamento. Então: para structs a alocar dinamicamente SEMPRE use sizeof() para calcular o tamanho a alocar. NUNCA some os bytes na mão apenas.

 

 

Postado
37 minutos atrás, arfneto disse:

Porque não tentou ao menos rodar um programa assim?



 

 

Na verdade há um bug nesse trecho também. Ele funciona apenas naquelas maquinas (ou compiladores) que definem char com 1 byte. Situação essa, por sinal, muito comum e que induz as pessoas a cometerem esse errinho e até acharem normal. Razões históricas: o standard de C recomenda 1 byte para char mas nem todos os desenvolvedores de hardware seguem padrões de linguagens de programação (normalmente o inverso ocorre). Por vezes, tampouco os desenvolvedores de compiladores seguem.

 

Por exemplo, eu trabalho com um compilador in-house no qual char é apenas um int convencional. Nele o seu exemplo já não funciona da maneira esperada.

 

Na duvida, seguimos boas práticas: nunca confie em soluções que dependem da maquina na qual vai rodar.

Postado
23 minutos atrás, V!OLADOR disse:

Na verdade há um bug nesse trecho também. Ele funciona apenas naquelas maquinas (ou compiladores) que definem char com 1 byte. Situação essa, por sinal, muito comum e que induz as pessoas a cometerem esse errinho e até acharem normal

 

Não, não há. É exatamente o contrário. sizeof(0 foi escrito para isso.
 

24 minutos atrás, V!OLADOR disse:

Por exemplo, eu trabalho com um compilador in-house no qual char é apenas um int convencional. Nele o seu exemplo já não funciona da maneira esperada

 

Tentou ao menos rodar o exemplo que te mostrei? sizeof(char) em seu compilador deve retornar 4. Mesmo que seja um cross-compiler, a menos que tenha sido escrito por um grupo de mulas. E fgets() vai funcionar de acordo.

 

Se ler a documentação, ao menos a primeira página, do que te mostrei vai ver 

 

image.png.58f78cc8682fb3a2aa5e794f14d05521.png

 

Que ilustra o fato de sizeof(0 retornar o valor correto para a máquina em que o programa está rodando

 

 

10 horas atrás, V!OLADOR disse:

Caso mais tarde o mesmo vetor venha a ser alocado dinamicamente, é muito provável que vários bugs, por vezes difíceis de resolver, apareçam. Principalmente se o projeto é grande (vários arquivos fontes, milhares de linhas de código etc)

 

Nada teria a ver com o projeto ou o tamanho. Seria apenas o uso inadequado de um operador. sizeof() na documentação 


image.png.dd8cae747a23fc59e625a9c91ed109d6.png

E você vê que nada teria a ver com um bloco de memória alocado dinamicamente...

 

10 horas atrás, V!OLADOR disse:

Uma boa pratica seria não usar sizeof pra determinar numero de elementos, apenas numero de bits. Principalmente quando os vetores em questão são alocados estaticamente

 

Tem alguma referência sobre essa "boa prática"?  Eu nunca vi uma implementação assim desse operador em 40 anos de C

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!