Ir ao conteúdo
  • Cadastre-se

C Output de string estranho


Visitante
Ir à solução Resolvido por JorgeGus,

Posts recomendados

Bom estou com o seguinte codigo:

#include <stdio.h>
  
int main(void){
	
  	char s[] = "texto";
  	char *c = (char*) &s;
  
  	for(int i=0;i<5;i++){
    	printf("%c", *c + i);
    }
  
	return 0;
}

 

Eu não estou entendendo porque o meu output é "tuvwx" e não "texto". Porque quando eu passo "*c + i" dentro do printf ele deveria andar um byte e printar a segunda string no array.

Usando "puts(c)" ele printa normal a palavra "texto"

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Por isso que eu digo que vetores, ponteiros e afins são pra mim entidades sobrenaturais. Você, caro autor ou membro experiente, consegue explicar passo a passo o que acha que a função deveria fazer?

7 horas atrás, XPointersX disse:
char *c = (char*) &s;

Algo como s= o endereço do conteúdo do endereço ? .. aff

😁

  • Amei 1
Link para o comentário
Compartilhar em outros sites

  • Solução
#include <stdio.h>

int main(void) {
    char s[] = "texto";
    char *c = s;

    for (int i = 0; i < 5; i++) {
        printf("%c", *(c + i));
    }
    return 0;
}

Faltou colocar parênteses para indicar que o valor deve ser somado ao endereço e não ao conteúdo do endereço.

No caso você estava fazendo:

't' + 0 = 't'

't' + 1 = 'u'

't' + 2 = 'v'

't' + 3 = 'w'

't' + 4 = 'x'

 

E um array já é um ponteiro para o primeiro elemento, então não é necessário fazer o casting de s para char*.

 

Você poderia substituir

printf("%c", *(c + i));

por

printf("%c", c[i]);

 

Link para o comentário
Compartilhar em outros sites

11 horas atrás, XPointersX disse:

Porque quando eu passo "*c + i" dentro do printf ele deveria andar um byte e printar a segunda string no array.

 

Pois é. Só que não deveria

 

11 horas atrás, XPointersX disse:

Usando "puts(c)" ele printa normal a palavra "texto"

 

Sim, porque assim é.

 

E porque afinal?

 

O programa está certo, o compilador está certo. O que está errado se quer mostrar a string é que

 

	printf("%c", *c + i);

 

devia ser

 

	printf("%c", *(c + i));

 

Assim estaria bem:

 

#include <stdio.h>

int main(void)
{
    char  s[] = "texto";
    char* c   = (char*)&s;

    for (int i = 0; i < 5; i++) { printf("%c", *(c + i)); }

    return 0;
}

 

mas dever preferir SEMPRE

 

#include <stdio.h>
int main(void)
{
    const char s[] = "texto";
    const char* c   = s;

    for (int i = 0; i < 5; i++) printf("%c", *(c + i));
    printf("\n");

    puts(s), puts(c); // exemplo

    printf("\n\t *s vale %d em decimal (%c)\n", *s, *s); // exemplo
    return 0;
}

 

porque a string é constante e assim o ponteiro também deve ser declarado como tal. Porque?

  • Nem todos os seus programas vão ter 5 linhas. E se resolver mudar algo na string --- de propósito ou por engano --- se declarar assim como const o compilador vai te avisar e não um telefonema no meio da noite ou um ponto a menos na nota com uma observação.
  • não use chaves a toa onde não precisa
  • mude de linha ao final da mensagem. É melhor do que deixar pra depois e colocar uma outra linha abaixo no programa que mostra outra coisa e sair tudo grudado e aí ter que voltar e mudar o que já devia ter feito.


Porque puts() funciona

 

puts() é como o loop que tentou escrever, só que pega o endereço inicial e põe na tela tudo o que tiver até achar um zero. Claro que ao declarar
 

        char s[] = "texto";

 

o zero está garantido depois do  'o'.

 

puts() funciona tanto para s e c 

 

    puts(s), puts(c);

 

porque são dois ponteiros para o mesmo lugar. Note que puts() mostra uma string por linha.

 

E porque "tuvwx"? 

 

Ao declarar 

 

    const char s[] = "texto";
    const char* c   = s;

 

s passa a apontar para uma área de memória com 6 bytes e lá estará a string com o zero no fim. É C afinal.

 

E c é um ponteiro e vai apontar para o mesmo endereço que s. 

 

*s e *c então são, claro, char, o "t". 
 

image.png.330ac2b2dc9297b1a1aa8dcd08f685dc.png


Quando você escreve 

 

    for (int i = 0; i < 5; i++) printf("%c", *(c + i));

 

Vai ver t, 116 na tabela, e depois 117, 118, 119, 120 😉 porque está somando ao valor de *c e não mostrando o endereço em 'c + i'

 

Veja os valores acima num trecho da tabela ASCII.

 

 

 

 

 

Link para o comentário
Compartilhar em outros sites

@XPointersX Sim, está errado. Leia o que eu expliquei. Tem mais exemplos e uma descrição do problema

4 horas atrás, .if disse:

Algo como s= o endereço do conteúdo do endereço ? .. aff

 

Sim, mas nem precisava disso tudo. s já é implicitamente char*. Veja o que eu disse no tópico #5

 

    char  s[] = "texto";
    char* c   = (char*)&s;

 

s é char[6], mas em C todo vetor é isso, base e deslocamento. Um endereço de início e o tamanho.

 

Então pode escrever 

 

    const char  s[] = "texto";
    const char* c   = s;

 

E c é um ponteiro pra char e aponta para o mesmo lugar que s. E lá estão 6 bytes com o conteúdo declarado. 

Link para o comentário
Compartilhar em outros sites

@arfneto  Muito obrigado pela resposta, mas eu tenho outra pergunta. Se quando eu chamo um ponteiro de um vetor eu estou chamando o valor do endereço do vetor certo? Então eu estou chamando um endereço da stack? porque o vetor não foi alocado dinamicamente.

Link para o comentário
Compartilhar em outros sites

@XPointersX

2 minutos atrás, XPointersX disse:

Se quando eu chamo um ponteiro de um vetor

 

Não entendo o que seria "chamar um ponteiro de um vetor". Talvez pudesse postar outra pergunta já que é outra mesmo 😄 

 

Um ponteiro aponta para um endereço. Só isso. Tanto faz se está ou não no stack, se é válido ou inventado (isso até você tentar usar).

 

Link para o comentário
Compartilhar em outros sites

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!