Ir para o conteúdo
Inacabado

[Resolvido] Copiar string: segmentation fault

Mensagens Recomendadas

Inacabado

Muito boa noite ao forum. Muito boa noite ao Happy Hippo.

Tenho um problema no seguinte código:

#include <stdio.h>
void CpStr(char v2[], char v1[]);
int main()
{
char v1[]="COSMOS";
char v2[20]={0};
CpStr(v2,v1);
puts(v1);
return 0;
}
void CpStr(char v2[], char v1[])
{
int i=0;
while ((v2[i]=v1[i])!='\0')
    i++;	
}

Estou a rever strings especialmente as regras para enviar strings/arrays como argumentos para funções. Daí montei este código, mas está-me a dar

segmentation fault (core dumped)

. Não está a dar nenhum erro de código apenas este ultimo erro.

Agradecia imenso a vossa ajuda. Abraço a todos.

Editado por Inacabado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Se souberes o que define uma string, acho que resolves o problema!

o que o PsySc0rpi0n quer dizer/perguntar é : o que faz com que um conjunto de bytes (como as tuas variáveis v1 e v2), sejam consideradas como uma string ?

ou melhor, qual o elemento fundamental da uma c-style string ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Ora bem sem consulta e baseado no meu conhecimento (que pode estar incompleto) sobre este dominio das strings/arrays. Digo que uma string em c é um array de caracteres. O nome da string aponta sempre para o primeiro endereço do vector. A minha intuição diz-me que faltará um apontador no vector v2. Será por aí???

Muito obrigado pela paciência; até já.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

(que pode estar incompleto) ... Digo que uma string em c é um array de caracteres

sim está incompleto.

uma string é um array de "caracteres" com uma particularidade no fim, qual é ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Ora bem a particularidade no fim é ter um caracter terminador o

 '\0'

. Vou tentar correr o programa de novo colocando-lhe o caracter terminador no final do vector v2.

(...)

Agora a função ficou assim:

void CpStr(char v2[], char v1[])
{
    int i=0;
    while ((v2[i]=v1[i])!='\0')
		    i++;
    v2[i++]= '\0';
}

e... voilá correu sem espinhas. O que é que eu hei-de dizer (sem bajulices desnecessárias) és o anjo padroeiro deste dominio do forum. Muito muito obrigado Happy. Abraço cordial

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Acho que nem é necessária a última linha de código porque no argumento do while acho que o '\0' já é copiado. Mas não tenho a certeza. Só testando.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Acho que nem é necessária a última linha de código porque no argumento do while acho que o '\0' já é copiado. Mas não tenho a certeza. Só testando.

Ele não copia o '\0' no while! Tanto que a condição diz claramente enquanto for diferente do caratcter terminador. No entanto, pode-se dispensar sim o

v2[i++]= '\0'

;porque em caso de ausência ele é acrescentado automáticamente em linguagem c.

Fiz o teste e dispensa esta ultima linha de código!

Já agora um muito obrigado tb pela tua ajuda.

Até breve

p.s. O código inicial deste tópico já foi alterado, e corre bem. Para o caso de alguém com o mesmo problema vir ver este tópico e não compreender onde é que está o erro!!! O erro estava em que eu estava a colocar o

while ((v2[i]=v1[i])!='\n')

, em vez de

while ((v2[i]=v1[i])!='\0')

.

Ou seja era no que os meus colegas me chamaram a atenção: o caracter terminador

'\0')

.

Editado por Inacabado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Ele não copia o '\0' no while! Tanto que a condição diz claramente enquanto for diferente do caratcter terminador.

sim copia, isto porque a cópia do caracter é efectuada antes da comparação (toma nota dos parenteses)

No entanto, pode-se dispensar sim o

v2[i++]= '\0'

;porque em caso de ausência ele é acrescentado automáticamente em linguagem c.

não.

a linguagem não faz nada por ti, o caracter '\0' tem sempre de existir


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

sim copia, isto porque a cópia do caracter é efectuada antes da comparação (toma nota dos parenteses)

Certo, estava-me a esquecer dos parenteses.

Mas então a comparação com o caracter terminador é redundante. Pode o código perfeitamente ficar assim:

while (v2[i]=v1[i])
	i++;

E o código corre que já testei.

a linguagem não faz nada por ti, o caracter '\0' tem sempre de existir

Mas é o compilador que coloca o caracter terminador. Eu nunca me preocupo em colocá-lo mas sim em ter atenção em reservar espaço para o mesmo.

Quando declarei a string

char v1[]="COSMOS";

Nunca me preocupei em colocar o '\0'. O compilador calcula o número de caracteres da string e adiciona o terminador automáticamente.

Editado por Inacabado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Certo, estava-me a esquecer dos parenteses.

Mas então a comparação com o caracter terminador é redundante. Pode o código perfeitamente ficar assim:

while (v2[i]=v1[i])
       i++;

E o código corre que já testei.

sim, mas somente por uma particulariedade, o caracter '\0' tem o valor numérico de zero (0)

como esse valor será usado como avaliação do ciclo, e zero representa falso, e ciclo termina.

não é magia nenhuma ...

Mas é o compilador que coloca o caracter terminador. Eu nunca me preocupo em colocá-lo mas sim em ter atenção em reservar espaço para o mesmo.

Quando declarei a string

char v1[]="COSMOS";

Nunca me preocupei em colocar o '\0'. O compilador calcula o número de caracteres da string e adiciona o terminador automáticamente.

o compilador não coloca o carater

tens de perceber é que a string "COSMOS", é uma string existente em memória (que o compilador a cria por ti, que nem podes alterar), e tem o caracter terminador lá no fim.

em termos práticos, o que estás a fazer com esse código é o mesmo que:

char v1[] = {'C', 'O', 'S', 'M', 'O', 'S', '\0'};


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

sim, mas somente por uma particulariedade, o caracter '\0' tem o valor numérico de zero (0)

como esse valor será usado como avaliação do ciclo, e zero representa falso, e ciclo termina.

não é magia nenhuma ...

Percebi isso mesmo á pouco quando consultei o livro " C e Algoritmos". Mas obrigado pela explicação

o compilador não coloca o carater

tens de perceber é que a string "COSMOS", é uma string existente em memória (que o compilador a cria por ti, que nem podes alterar), e tem o caracter terminador lá no fim.

em termos práticos, o que estás a fazer com esse código é o mesmo que:

char v1[] = {'C', 'O', 'S', 'M', 'O', 'S', '\0'};

Isso é o mesmo que dizer que não sou eu que coloco o caracter terminador '\0'! A linguagem ou o compilador, ou o que seja colocam o caracter terminador automáticamente no fim da string. Mas ainda segundo o Livro do Luís Damas é o compilador que coloca o caracter terminador, no final da string. Acabei de consultar o livro para fundamentar (ou admitir o erro a haver) sobre este pequeno debate. Peço desculpas.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

O facto de usar as aspas (" ... ") implica que o tal caractér terminador de uma string seja adicionado à string... Seja aquando da compilação ou seja quando for!...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Isso é o mesmo que dizer que não sou eu que coloco o caracter terminador '\0'! A linguagem ou o compilador, ou o que seja colocam o caracter terminador automáticamente no fim da string. Mas ainda segundo o Livro do Luís Damas é o compilador que coloca o caracter terminador, no final da string. Acabei de consultar o livro para fundamentar (ou admitir o erro a haver) sobre este pequeno debate. Peço desculpas.

o livro do luis damas tem a sua fama e não vou comentar ...

o que quero dizer é : se declaras uma string, então estás a declarar também o caracter terminador ('\0'), como te amostrei anteriormente, a declaração de uma string é a mesma coisa que a declaração de uma array de caracteres com o caracter terminador no fim.

por outras palavras, és tu que estás a declarar o caracter, ele não aparece por magia.


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

o livro do luis damas tem a sua fama e não vou comentar ...

Eu acredito que o Livro do Luís Damas não é infalível. Até prefiro aprender "in loco" com programadores experimentados, como é o teu caso do que por livros. Respeito imenso a tua experiência e toda a ajuda que sempre tens dado no fórum. E para mim têm sempre muito crédito as tuas intervenções. Mais do que livros prefiro opiniões de programadores "batidos". Muito obrigado por toda a ajuda.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.