Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Fala galera beleza? Estou com um problema para conseguir copiar uma lista (que o usuário insere os dados) para uma outra lista.
aqui esta o que eu ja fiz.
#include <stdio.h>
#include <stdlib.h>
struct lista {
int info;
struct lista *prox;
};
struct lista addItem (struct lista *cabeca){
struct lista *atual,*novo;
atual = cabeca;
system("cls");
printf("Digite a informacao\n");atual= atual->prox;
}
novo = (lista*) malloc (sizeof (lista));
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}
void imprime(struct lista *cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}
struct lista *inicializa(){
return NULL;
}
struct lista copiar (struct lista lista1,struct lista lista2) {
system("cls");
struct lista *p,*q,*aux;
q = lista2;
for (p=lista1; p->prox != NULL; p=p->prox) {
q->info=p->info;
q=q->prox;
}
printf("Copia completa\n");
}
int main () {
int j;
struct lista *lista1;
lista1 = (lista*) malloc (sizeof (lista));
lista1->prox = inicializa();
struct lista *lista2;
lista2 = (lista*) malloc (sizeof (lista));
lista2->prox= inicializa();printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para copiar a lista\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
printf("Escolha se voce quer inserir na lista 1 ou na lista 2\n");
scanf("%d",&j);
if (j==1){
addItem(lista1);
}
else if (j==2){
addItem(lista2);
}
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(lista1);
}
else if (j==2){
imprime(lista2);
}
} else if (j==3){
copiar(lista1,lista2);
}
} while (j!=0);
}
O meu objetivo é transferir os elementos da lista 1 para a lista 2 e assim ter duas listas idênticas na impressão.
Pode-se ver que a função copiar não esta funcionando ( o programa trava). Obrigado pela ajuda desde já =D
Primeiramente obrigado ScreenBlack, bem fiz as modificações que você falou e também passei as funções struct lista copiar e struct lista addItem para void copiar e void addItem, pois n tenho nenhuma intenção de retornar um valor nessas funções. Só que agora o programa n permite inserir dados ( ele trava). Anteriormente o programa inseria e imprimia os items corretamente( apenas não copiava). Mas o meu problema principal ainda é a copia, e mesmo se a lista1 tiver mais elementos q a lista2 eu queria que todos os elementos fossem copiados, até os excedentes.
Código atual:
#include <stdio.h>
#include <stdlib.h>
struct lista {
int info;
struct lista *prox;
};
void addItem (struct lista **cabeca){
struct lista *atual,*novo;
atual = *cabeca;
system("cls");
printf("Digite a informacao\n");atual= atual->prox;
}
novo = (lista*) malloc (sizeof (lista));
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}
void imprime(struct lista **cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = *cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}
struct lista *inicializa(){
return NULL;
}
void copiar (struct lista lista1,struct lista lista2) {
system("cls");
struct lista *p,*q,*aux;
q = *lista2;
for (p=*lista1; p->prox != NULL; p=p->prox) {
q->info=p->info;
q=q->prox;
}
printf("Copia completa\n");
}
int main () {
int j;
struct lista *lista1;
lista1 = (struct lista*) malloc( sizeof(struct lista) );
lista1= inicializa();
struct lista *lista2;
lista2 = (struct lista*) malloc (sizeof (struct lista));
lista2 = inicializa();printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para copiar a lista\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
printf("Escolha se voce quer inserir na lista 1 ou na lista 2\n");
scanf("%d",&j);
if (j==1){
addItem(&lista1);
}
else if (j==2){
addItem(&lista2);
}
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(&lista1);
}
else if (j==2){
imprime(&lista2);
}
} else if (j==3){
copiar(&lista1,&lista2);
}1) Você esqueceu de especificar o tipo completo no "malloc()" da função "addItem()".
novo = (struct lista*) malloc ( sizeof(struct lista) );
2) Você declarou o retorno das função para ponteiro void, que é diferente de apenas void.
void addItem (struct lista **cabeca)
void imprime(struct lista **cabeca)
3) O programa está fechando, porque na função "main()", está sendo alocada memória para o primeiro elemento da lista e em seguida setando a lista pra NULL, perdendo assim a referência para o primeiro elemento.
Além disso, a função "addItem()" não está fazendo a verificação se já existe o primeiro elemento válido na lista.
Aconselho deixar toda a parte de alocação de memória para inserção de novos elementos, na função "addItem()", apenas.
Trecho que mostra a alocação e depois setando pra NULL, que é o retorno da função "inicializa()":
lista1 = (struct lista*) malloc( sizeof(struct lista) );
lista1= inicializa();Se não é pra ser "ponteiro void' como eu deveria fazer a declaração da função?
Ps: Fiz a especificação do tipo completo na função addItem e continua n funcionando.
Em meu post anterior, no item 2, mostra a declaração sem ponteiro void.
No item 3, informa o porque seu programa está sendo fechado de maneira inesperada.
A sim, me desculpe deu algum bug no meu navegador e não apareceu os últimos items. Fiz o que você falou e agora estou conseguindo inserir os items. Mas a função copiar ainda n funciona. Alguma ideia?
Mostre como ficou seu código após a alteração.
Aqui o código
#include <stdio.h>
#include <stdlib.h>
struct lista {
int info;
struct lista *prox;
};
struct lista **inicializa(){
return NULL;
}
void addItem (struct lista **lista1) {
struct lista *atual,*novo;
lista1 = (struct lista**) malloc( sizeof(struct lista) );
lista1= inicializa();
atual = *lista1;
system("cls");
printf("Digite a informacao\n");atual= atual->prox;
}
novo = (struct lista*) malloc ( sizeof(struct lista) );
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}
void imprime(struct lista **cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = *cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}
void copiar (struct lista lista1,struct lista lista2) {
system("cls");
struct lista *p,*q,*aux;
q = *lista2;
for (p=*lista1; p->prox != NULL; p=p->prox) {
q->info=p->info;
q=q->prox;
}
printf("Copia completa\n");
}
int main () {
int j;
struct lista *lista1;
struct lista *lista2;printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para copiar a lista\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
printf("Escolha se voce quer inserir na lista 1 ou na lista 2\n");
scanf("%d",&j);
if (j==1){
addItem(&lista1);
}
else if (j==2){
addItem(&lista2);
}
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(&lista1);
}
else if (j==2){
imprime(&lista2);
}
} else if (j==3){
copiar(&lista1,&lista2);
}
} while (j!=0);
}Não função "addItem()", está sendo setado NULL para o ponteiro errado.
E, também, permanece o mesmo equívoco de definir NULL após uma alocação de memória, fazendo com que seja perdida a referência pra essa alocação.
*lista = (struct LISTA *) malloc( sizeof(struct LISTA) );
atual = *lista;Só uma observação: em C não é preciso fazer cast do retorno de malloc. Garanta que realmente está usando um compilador de C, e não de C++.
Bem eu uso o Dev-C pois é o compilador que meu professor recomenda.
Eu consegui fazer a função copiar funcionar, mas apenas no meu programa antigo, ou seja sem usar ponteiro para ponteiro.
Eu não consegui achar em lugar nenhum uma função de copiar lista para outra lista sem usar recursividade. Por isso vou postar o meu programa aqui para que outros não tenham o mesmo problema, esse programa também remove elementos da lista e concatena as duas.
#include <stdio.h>
#include <stdlib.h>
struct lista {
int info;
struct lista *prox;
};
struct lista addItem (struct lista **cabeca){
struct lista *atual,*novo;
atual = *cabeca;
system("cls");
printf("Digite a informacao\n");atual= atual->prox;
}
novo = (lista*) malloc (sizeof (lista));
scanf("%d",&atual->info);
novo->prox = NULL;
atual->prox= novo;
}
void imprime(struct lista *cabeca) {
system("cls");
struct lista *p;
printf("Elementos: \n");
for (p = cabeca; p->prox != NULL; p = p->prox) {
printf( " * %d\n",p->info);
}
}
char verifica(struct lista *cabeca) {
//buscar um elemento na lista encadeada
int valor;
printf("Digite um valor a ser buscando");
scanf("%d",&valor);busca = 'S';
return busca;
}busca = 'N';
return busca;
}
struct lista *inicializa(){
return NULL;
}
struct lista remover (struct lista *cabeca) {
system("cls");
int y;
printf("Digite a informacao a ser removida");
scanf("%d",&y);
lista *p, *q;
p = cabeca;
q = cabeca->prox;p = q;
q = q->prox;
}
if (q != NULL) {
p->prox = q->prox;
free( q);
}
printf("Informacao Removida da lista\n");
}
struct lista copiar (struct lista L,struct lista *l2) {
struct lista *atual = L;
struct lista *novo;l2->info = atual->info;
novo = (lista*) malloc (sizeof (lista));
novo->prox = NULL;
l2->prox = novo;
l2=l2->prox;
atual=atual->prox;
}
printf("Copia completa\n");
}
struct lista concatena (struct lista lista1,struct lista lista2) {
system("cls");
lista *p,*q,*aux;p = lista1;
lista1 = lista1->prox;
}while(lista1->prox != NULL);
p->prox = lista2;
printf("Concatecacao completa\n");
}
int main () {
int j;
struct lista *lista1;
lista1 = (struct lista*) malloc( sizeof(struct lista) );
lista1->prox = inicializa();
struct lista *lista2;
lista2 = (lista*) malloc (sizeof (lista));
lista2->prox= inicializa();
struct lista *listacopy;printf("Escolha uma das funcoes\n");
printf("Digite [1] para Inserir items\nDigite [2] para imprimir a lista\nDigite [3] para verificar se o numero pertence a lista\nDigite [4] para remover um numero pertencente a lista\nDigite [5] para copiar a lista 1 para lista 2\nDigite [6] para concatenar as listas\nDigite [0] para encerrar o programa\n");
scanf("%d",&j);
if (j==1){
addItem(&lista1);
} else if (j==2) {
printf("Escolha se voce quer imprimir a lista 1 ou a lista 2\n");
scanf("%d",&j);
if (j==1){
imprime(lista1);
}
else if (j==2){
imprime(lista2);
}
} else if (j==3) {
printf("\n'S' significa que ha o valor na lista 'N' Nao ha o valor na lista\nA busca retornou: %c\n",verifica(lista1));
} else if (j==4) {
remover (lista1);
} else if (j==5){
copiar(lista1,lista2);
} else if (j==6) {} while (j!=0);
}
Queria agradecer a todos, e se tiverem mais algum conselho podem comentar ae =P
Beleza.
Agora apresento o código que fiz, baseado no seu, para comparação: http://pastebin.com/uRbjnAhh
Está funcionando a alocação e desalocação de memória, também para a lista 2, antes de receber os valores da lista 1.
Segue a última lista que implementei em C, caso achem útil:
Vocês saberiam me explicar porque no meu compilador (Dev-C) quando eu executo o programa do Screen aparece esses erros?
In function 'void addItem(LISTA**)':
29 47 [Error] invalid conversion from 'void' to 'LISTA' [-fpermissive]
37 52 [Error] invalid conversion from 'void' to 'LISTA' [-fpermissive]
In function 'void copiar(LISTA, LISTA)':
77 52 [Error] invalid conversion from 'void' to 'LISTA' [-fpermissive]
83 56 [Error] invalid conversion from 'void' to 'LISTA' [-fpermissive]
Creio que foi isso que impediu o aproveitamento das dicas dadas aqui.
Isso está com cara de ser o compilador contido no Dev-C.
Você está usando a versão Bloodshed?
O projeto foi continuado pela Orwell: http://orwelldevcpp.blogspot.com.br/
Quem sabe a nova versão funcione melhor.
Parece que esse compilador é de C++.
No Windows, sugiro usar o MinGW.
Se você tem o tamanho da lista e sua base então é só armazenar memória para a outra lista que receberá a cópia e copiar com memcpy.
Veja:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct lista {
int info;
struct lista *prox;
};
int main()
{
struct lista *base, *l1, *l2;
struct lista *node;
int lista_len = 0;
int i;
int len;
for (i = 0; i < 5; i++, lista_len++)
{
node = (struct lista*) malloc(sizeof(struct lista));
node->info = i+1;
node->prox = NULL;
if (lista_len == 0)
{
l1 = node;
base = node;
}
else
{
base->prox = node;
base = base->prox;
}
}
//Copiando l1 para l2;
len = sizeof(struct lista) * lista_len;
l2 = (struct lista*) malloc(len);
memcpy(l2, l1, len);
//Verificando se copiou
while (l2->prox != NULL)
{
node = l2;
printf("Info: %d\n", node->info);
l2 = l2->prox;
}
return 0;
}Ah essa função memcopy é realmente muito útil, n sabia dela. Com certeza diminui o trabalho no código. Vlw!!!
Alguns erros que encontrei.
1) Na alocação de memória, não é especificada a expressão completo do tipo.
lista1 = (struct lista*) malloc( sizeof(struct lista) );
2) Nas funções "copiar()" e "addItem()" , não possui retorno para o tipo dessas funções.
struct lista copiar (...)
struct lista addItem (...)
3) Na função "addItem()", precisa receber ponteiro para ponteiro, para que seja possível alterar o valor inicial da lista, sem perder a relação inicial.
void addItem (struct lista **cabeca)
Modificar dentro da função "addItem()" para:
atual = *cabeca;
Alterar as chamadas na função "main()":
4) Função "copiar()" faz a cópia do valor contido na lista 1 para a lista 2, sem conferir a quantidade de elementos existentes em cada um. Isso permitindo gravar valor excedentes na lista 2, caso a lista 1 possua mais elementos.