elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Agenda de contactos en C mediante listas enlazadas [Código]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Agenda de contactos en C mediante listas enlazadas [Código]  (Leído 9,484 veces)
Rhessus

Desconectado Desconectado

Mensajes: 11


Ver Perfil
Agenda de contactos en C mediante listas enlazadas [Código]
« en: 24 Agosto 2016, 18:00 pm »

Mis agradecimientos de manera especial a AlbertoBSD, por su incondicional ayuda a cada una de mis dudas, y a mi profesora (llamémosla "L", no me gusta dejar información personal de otros en Internet), por su infinita paciencia y ayuda incansable.

Nota: el código es corregible (o sea, no es perfecto... pero prefiero dejarlo así, tal y como lo entregué; con el añadido de una sola aclaración). Para comprender el mismo, es necesario conocimiento básico en C (punteros, arrays, estructuas y memoria dinámica).

Código
  1. /***************************************************************************************************************************/
  2.  
  3.                   /***  LABORATORIO DE PROGRAMACIÓN II- TRABAJO PRÁCTICO FINAL: AGENDA DE CONTACTOS  ***/                  
  4.  
  5. /***************************************************************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. #define N 300  //cantidad de caracteres para el espacio en memoria para las cadenas
  12. #define M 30   //cantidad de caracteres para las cadenas
  13.  
  14. /***************************************************************************************************************************/
  15.  
  16. typedef struct direccion{
  17.  
  18. char calle[N];
  19. char numero[N];
  20.  
  21. } _direccion;
  22.  
  23. /***************************************************************************************************************************/
  24.  
  25. typedef struct contact {
  26.  
  27. char name[N];
  28. char number[N];
  29. char mail[N];
  30. _direccion address;
  31. struct contact *next;
  32.  
  33. } Contact;
  34.  
  35. /***************************************************************************************************************************/
  36.  
  37. Contact *head = NULL;
  38. Contact *tail = NULL;
  39.  
  40. /***************************************************************************************************************************/
  41.  
  42. void imprimirSeparador() { printf("=================================\n"); }
  43.  
  44. /***************************************************************************************************************************/
  45.  
  46. void imprimirOpciones() {
  47.  
  48.    imprimirSeparador();
  49.    printf("Agenda\n");
  50.    printf("======\n");
  51.    printf("1. Agregar contacto\n");
  52.    printf("2. Mostrar contactos\n");
  53.    printf("3. Mostrar contactos por letra\n");
  54.    printf("4. Buscar contactos por nombre\n");
  55.    printf("5. Buscar contactos por teléfono\n");
  56.    printf("6. Eliminar contacto por nombre\n");
  57.    printf("7. Eliminar todos los contactos\n");
  58.    printf("8. Salir\n");
  59.    imprimirSeparador();    
  60.  
  61. }
  62.  
  63. /***************************************************************************************************************************/
  64.  
  65. //se encarga de leer nombre, teléfono, mail y dirección del contacto que se desea agregar,
  66. //llama a nuevoContactoLista(...) para agregarlo a la lista de ser posible y
  67. //finalmente comunica al usuario el resultado de la operación
  68. void nuevoContacto(){
  69.  
  70. Contact *new;
  71. new = (Contact *)malloc(sizeof(Contact));
  72.  
  73. imprimirSeparador();
  74.  
  75. printf("Contacto nuevo\n");
  76. printf("==============\n");
  77.  
  78. printf("Nombre: ");
  79. scanf("%s", new->name);
  80.  
  81. while(strlen(new->name) > M){ //si la cadena es demasiado larga
  82. imprimirSeparador();
  83. printf("El nombre es demasiado largo. Intenta nuevamente con uno más corto.\n");
  84. printf("Nombre: ");
  85. scanf("%s", new->name);
  86. }
  87.  
  88. printf("Teléfono: ");
  89. scanf("%s", new->number);
  90.  
  91. while(strlen(new->number) > M){ //si la cadena es demasiado larga
  92. imprimirSeparador();
  93. printf("El número de teléfono es demasiado largo. Intenta nuevamente con uno más corto.\n");
  94. printf("Teléfono: ");
  95. scanf("%s", new->number);
  96. }
  97.  
  98.  
  99. printf("Mail: ");
  100. scanf("%s", new->mail);
  101.  
  102. while(strlen(new->mail) > M){ //si la cadena es demasiado larga
  103. imprimirSeparador();
  104. printf("El mail es demasiado largo. Intenta nuevamente con uno más corto.\n");
  105. printf("Mail: ");
  106. scanf("%s", new->mail);
  107. }
  108.  
  109. printf("Dirección: ");
  110. scanf("%s%s", new->address.calle, new->address.numero);
  111.  
  112. while(strlen(new->address.calle) > M || strlen(new->address.numero) > M){ //si la cadena es demasiado larga
  113. imprimirSeparador();
  114. printf("La dirección es demasiado larga. Intenta nuevamente con una más corta.\n");
  115. printf("Dirección: ");
  116. scanf("%s%s", new->address.calle, new->address.numero);
  117. }
  118.  
  119. imprimirSeparador();
  120.  
  121. nuevoContactoLista(new->name, new->number, new->mail, new->address.calle, new->address.numero);
  122.  
  123. free(new);
  124. }
  125.  
  126. /***************************************************************************************************************************/
  127.  
  128. //recibe como argumento nombre, teléfono, mail y dirección del contacto que se desea agregar,
  129. //si no existe ningún otro contacto con el mismo nombre lo agrega a la lista
  130. void nuevoContactoLista(char name[], char number[], char mail[], _direccion addressCalle[], _direccion addressNumero[]){
  131.  
  132. Contact *contactoNuevo, *aux;
  133. contactoNuevo = (Contact *)malloc(sizeof(Contact));
  134.  
  135. /**********************************************************************/
  136.  
  137. aux = head;
  138. while(aux != NULL) {
  139. if((strcmp(aux->name, name)) == 0){
  140. printf("El nombre de contacto ingresado ya existe.\n");
  141. return;
  142. }
  143. else{
  144. aux = aux->next;
  145. }
  146. }
  147. if(aux == NULL){
  148. strcpy(contactoNuevo->name, name);
  149. }
  150.  
  151. /**********************************************************************/
  152.  
  153. aux = head;
  154. while(aux != NULL) {
  155. if((strcmp(aux->number, number)) == 0){
  156. printf("El número de teléfono ingresado ya existe.\n");
  157. return;
  158. }
  159. else{
  160. aux = aux->next;
  161. }
  162. }
  163. if(aux == NULL){
  164. strcpy(contactoNuevo->number, number);
  165. }
  166.  
  167. /**********************************************************************/
  168.  
  169. strcpy(contactoNuevo->mail, mail);
  170.  
  171. /**********************************************************************/
  172.  
  173. strcpy(contactoNuevo->address.calle, addressCalle);
  174.  
  175. /**********************************************************************/
  176.  
  177. strcpy(contactoNuevo->address.numero, addressNumero);
  178.  
  179. /**********************************************************************/
  180.  
  181. contactoNuevo->next = NULL;
  182.  
  183. /**********************************************************************/
  184.  
  185. if(head == NULL){
  186. head = contactoNuevo;
  187. }
  188. else{
  189.        tail->next = contactoNuevo;
  190. }
  191.  
  192.    tail = contactoNuevo;
  193.    printf("La información del contacto ha sido guardada exitosamente.\n");
  194.  
  195. }
  196.  
  197. /***************************************************************************************************************************/
  198.  
  199. void imprimirContactos(){
  200.  
  201. Contact *auxiliar;
  202. int TAM;
  203.  
  204. imprimirSeparador();
  205.  
  206. /**********************************************************************/
  207.  
  208. //TAM = cantidad de contactos
  209.  
  210. auxiliar = head;
  211.  
  212. TAM = 0;
  213. while(auxiliar != NULL) {
  214. auxiliar = auxiliar->next;
  215. TAM++;
  216. }
  217.  
  218. /**********************************************************************/
  219. //Ordenamiento de burbuja: ordena alfabéticamente los contactos
  220. if(head != NULL){
  221. Contact *first = NULL, *second = NULL, *auxi = NULL;
  222.  
  223. first = head;
  224. while(first != tail){
  225. second = first->next;
  226. while(second != NULL){
  227. if(strcmp(first->name, second->name) > 0){
  228. strcpy(auxi->name, first->name);
  229. strcpy(auxi->number, first->number);
  230. strcpy(auxi->mail, first->mail);
  231. strcpy(auxi->address.calle, first->address.calle);
  232. strcpy(auxi->address.numero, first->address.numero);
  233.  
  234. strcpy(first->name, second->name);
  235. strcpy(first->number, second->number);
  236. strcpy(first->mail, second->mail);
  237. strcpy(first->address.calle, second->address.calle);
  238. strcpy(first->address.numero, second->address.numero);
  239.  
  240. strcpy(second->name, auxi->name);
  241. strcpy(second->number, auxi->number);
  242. strcpy(second->mail, auxi->mail);
  243. strcpy(second->address.calle, auxi->address.calle);
  244. strcpy(second->address.numero, auxi->address.numero);
  245. }
  246.  
  247. second = second->next;
  248. }
  249.  
  250. first = first->next;
  251. }
  252. }
  253.  
  254. /**********************************************************************/
  255.  
  256. auxiliar = head;
  257.  
  258. printf("Contactos\n");
  259.  
  260. while(auxiliar != NULL) {
  261. printf("=========\n");
  262. printf("Nombre:    %s\nTeléfono:  %s\nMail:      %s\nDirección: %s %s\n", auxiliar->name, auxiliar->number, auxiliar->mail, auxiliar->address.calle, auxiliar->address.numero);
  263. auxiliar = auxiliar->next;
  264. }
  265.  
  266. if(TAM == 0){
  267. printf("=========\n");
  268. printf("La agenda está vacía.\n");
  269. }
  270.  
  271. }
  272.  
  273. /***************************************************************************************************************************/
  274.  
  275. //lee la letra con que se quiere que empiecen los nombres de los contactos que se desean imprimir,
  276. //luego le pasa el caracter a la función encargada de imprimirlos
  277. void imprimirContactosLetra(){
  278.  
  279. char c[1];
  280.  
  281. imprimirSeparador();
  282.  
  283. printf("Ingrese la primera letra de los contactos que desea ver: ");
  284. scanf("%s", c);
  285.  
  286. imprimirContactosLetraLista(c);
  287.  
  288. }
  289.  
  290. /***************************************************************************************************************************/
  291.  
  292. //recibe un caracter e imprime todos los contactos cuyo nombre empieza con ese caracter
  293. void imprimirContactosLetraLista(char c[]){
  294.  
  295. Contact *aux;
  296. int i;
  297.  
  298. imprimirSeparador();
  299.  
  300. printf("Contactos que empiezan con la letra '%s'\n", c);
  301.  
  302. aux = head;
  303. i = 0;
  304. while(aux != NULL){
  305. if(strncmp(aux->name, c, 1) == 0){
  306. printf("=========\n");
  307. printf("Nombre:    %s\nTeléfono:  %s\nMail:      %s\nDirección: %s %s\n", aux->name, aux->number, aux->mail, aux->address.calle, aux->address.numero);
  308. aux = aux->next;
  309. i++;
  310. }
  311. else{
  312. aux = aux->next;
  313. }
  314. }
  315. if(i == 0){
  316. printf("=========\n");
  317. printf("No hay resultados.\n");
  318. }
  319.  
  320. }
  321.  
  322. /***************************************************************************************************************************/
  323.  
  324. //lee el nombre (o el inicio del mismo) que desea usarse para la búsqueda y se lo pasa a la función encargada de buscar
  325. void buscarContactosNombre(){
  326.  
  327. char nam[N];
  328.  
  329. imprimirSeparador();
  330.  
  331. printf("Ingrese el nombre, o el inicio del mismo, que desea utilizar para la búsqueda de contactos: ");
  332. scanf("%s", nam);
  333.  
  334. buscarContactosNombreLista(nam);
  335.  
  336. }
  337.  
  338. /***************************************************************************************************************************/
  339.  
  340. //recibe una cadena de caracteres y devuelve los contactos cuyo nombre comienza con dicha cadena
  341. //aclaración: NO debe diferenciar mayúsculas de minúsculas
  342. void buscarContactosNombreLista(char nam[]){
  343.  
  344. Contact *aux;
  345. int i;
  346.  
  347. imprimirSeparador();
  348.  
  349. printf("Contactos relacionados con '%s'\n", nam);
  350.  
  351. aux = head;
  352.  
  353. i = 0;
  354. while(aux != NULL){
  355. if(strncasecmp(aux->name, nam, strlen(nam)) == 0){
  356. printf("=========\n");
  357. printf("Nombre:    %s\nTeléfono:  %s\nMail:      %s\nDirección: %s %s\n", aux->name, aux->number, aux->mail, aux->address.calle, aux->address.numero);
  358. aux = aux->next;
  359. i++;
  360. }
  361. else{
  362. aux = aux->next;
  363. }
  364. }
  365.  
  366. if(i == 0){
  367. printf("=========\n");
  368. printf("No hay resultados.\n");
  369. }
  370.  
  371. }
  372.  
  373. /***************************************************************************************************************************/
  374.  
  375. //lee el teléfono (o el inicio del mismo) que desea usarse para la búsqueda y se lo pasa a la función encargada de buscar
  376. void buscarContactosTelefono(){
  377.  
  378. char num[N];
  379.  
  380. imprimirSeparador();
  381.  
  382. printf("Ingrese el teléfono, o el inicio del mismo, que desea utilizar para la búsqueda de contactos: ");
  383. scanf("%s", num);
  384.  
  385. buscarContactosTelefonoLista(num);
  386.  
  387. }
  388.  
  389. /***************************************************************************************************************************/
  390.  
  391. //recibe un teléfono (o parte de él) y devuelve los contactos cuyo teléfono empieza con ese número
  392. void buscarContactosTelefonoLista(char num[]){
  393.  
  394. Contact *aux;
  395. int i;
  396.  
  397. imprimirSeparador();
  398.  
  399. printf("Contactos cuyo teléfono está relacionado con '%s'\n", num);
  400.  
  401. aux = head;
  402. i = 0;
  403. while(aux != NULL){
  404. if(strncmp(aux->number, num, strlen(num)) == 0){
  405. printf("=========\n");
  406. printf("Nombre:    %s\nTeléfono:  %s\nMail:      %s\nDirección: %s %s\n", aux->name, aux->number, aux->mail, aux->address.calle, aux->address.numero);
  407. aux = aux->next;
  408. i++;
  409. }
  410. else{
  411. aux = aux->next;
  412. }
  413. }
  414.  
  415. if(i == 0){
  416. printf("=========\n");
  417. printf("No hay resultados.\n");
  418. }
  419.  
  420. }
  421.  
  422. /***************************************************************************************************************************/
  423.  
  424. //lee el nombre del contacto que se desea eliminar, solicita la confirmación del usuario,
  425. //llama a eliminarContactoNombreLista(...) la cual borra el contacto si es que existe y
  426. //finalmente comunica al usuario el resultado de la operación
  427. void eliminarContactoNombre(){
  428.  
  429. Contact *aux = head;
  430. int i = 0;
  431. char nom[N];
  432. int opc;
  433.  
  434. imprimirSeparador();
  435.  
  436. printf("Ingrese el nombre del contacto que desea eliminar: ");
  437. scanf("%s", nom);
  438.  
  439. imprimirSeparador();
  440.  
  441. while(aux != NULL){
  442. if(strcmp(aux->name, nom) == 0){
  443. i++;
  444. printf("¿Está seguro de querer eliminar a '%s' de la agenda?\n", nom);
  445. printf("1. Sí\n");
  446. printf("2. No\n");
  447.  
  448. imprimirSeparador();
  449.  
  450. scanf("%d", &opc);
  451.  
  452. switch(opc) {
  453.  
  454. case 1:
  455. eliminarContactoNombreLista(nom);
  456. break;
  457. case 2:
  458. return;
  459. break;
  460. default:
  461. break;
  462. }
  463. if(opc == 1){
  464. imprimirSeparador();
  465. printf("El contacto '%s' ha sido borrado de la agenda.\n", nom);
  466. }
  467. break;
  468. }
  469. else{
  470. aux = aux->next;
  471. }
  472. }
  473.  
  474. if(i == 0){
  475. printf("No existe ningún contacto con el nombre '%s'.\n", nom);
  476. }
  477.  
  478. }
  479.  
  480. /***************************************************************************************************************************/
  481.  
  482. //recibe un nombre, si existe algún contacto en la lista con ese nombre lo borra
  483. void eliminarContactoNombreLista(char nom[]){
  484.  
  485. Contact *aux_borrar;
  486. Contact *anterior = NULL;
  487.  
  488. aux_borrar = head;
  489.  
  490. while(strcmp(aux_borrar->name, nom) != 0){ //mientras el nombre no coincida con el nombre del contacto
  491. anterior = aux_borrar; //se pasará al siguiente contacto
  492. aux_borrar = aux_borrar->next;
  493. }
  494.  
  495. //salir del while significa que se encontró el contacto cuyo nombre coincide con el ingresado
  496.  
  497. if(aux_borrar->next != NULL){ //si el contacto ha ser eliminado NO es el ÚLTIMO
  498. if(aux_borrar != head){ // si el contacto no es el primero
  499. anterior->next = aux_borrar->next; //su anterior seguirá a su sucesor
  500. free(aux_borrar); //y el contacto será eliminado
  501. }
  502. else{ //si el contacto ES el PRIMERO
  503. head = aux_borrar->next; //el segundo se convertirá en el primero
  504. free(aux_borrar); //y el contacto será eliminado
  505. }
  506. }
  507. else{ //aux_borrar->next = NULL //si el contacto ha ser eliminado ES el ÚLTIMO
  508. if(aux_borrar != head){ //y si no es el primero (hay más contactos)
  509. anterior->next = NULL; //su anterior seguirá a NULL
  510. free(aux_borrar); //el contacto será eliminado
  511. tail = anterior; //y el anterior se convertirá en el último
  512. }
  513. else{ //si el contacto es el único (ES el PRIMERO y el ÚLTIMO)
  514. free(aux_borrar); //será eliminado
  515. head = NULL;
  516. tail = NULL;
  517. }
  518. }
  519.  
  520. }
  521.  
  522. /***************************************************************************************************************************/
  523.  
  524. //solicita la confirmación del usuario antes de borrar todos los contactos,
  525. //en caso de obtenerla llama a eliminarTodosContactosLista(...) y
  526. //finalmente muestra un mensaje apropiado
  527. void eliminarTodosContactos(){
  528.  
  529. imprimirSeparador();
  530.  
  531. printf("¿Está seguro de querer eliminar todos los contactos de la agenda?\n");
  532. printf("1. Sí\n");
  533. printf("2. No\n");
  534.  
  535. imprimirSeparador();
  536.  
  537. submenuTodosContactos();
  538.  
  539. }          
  540.  
  541. /***************************************************************************************************************************/
  542.  
  543. //sub-menú de la función eliminarTodosContactos()
  544. void submenuTodosContactos(){
  545.  
  546. Contact *auxil;
  547. int op;
  548.  
  549. int i;
  550.  
  551. auxil = head;
  552.  
  553. i = 0;
  554. while(auxil != NULL) {
  555. auxil = auxil->next;
  556. i++;
  557. }
  558.  
  559. scanf("%d", &op);
  560.  
  561. switch(op) {
  562.  
  563.            case 1:
  564.                eliminarTodosContactosLista();
  565.                break;
  566.            case 2:
  567.                return;
  568.            default:
  569.                break;
  570.        }
  571.  
  572.        imprimirSeparador();
  573.  
  574.        if(i != 0){
  575. printf("Todos los contactos de la agenda han sido borrados.\n");
  576. }
  577.        else {
  578. printf("No existen contactos en la agenda.\n");
  579. }
  580. }
  581.  
  582. /***************************************************************************************************************************/
  583.  
  584. //se encarga de borrar todos los nodos de la lista
  585. void eliminarTodosContactosLista(){
  586.  
  587.    Contact *con;
  588.  
  589.    if(head != NULL) {
  590. while(1) {
  591.        con = head;
  592.        head = head->next;
  593.        free(con);
  594.    }
  595.  
  596. tail = NULL;
  597. }
  598.  
  599. }
  600.  
  601. /***************************************************************************************************************************/
  602.  
  603. //liberar memoria al salir
  604. void liberarMemoria(){
  605.  
  606. imprimirSeparador();
  607.  
  608. printf("Programa cerrado.\n");
  609.  
  610. imprimirSeparador();
  611.  
  612. eliminarTodosContactosLista();
  613.  
  614. }
  615.  
  616. /**************************************************  FUNCIÓN MAIN()  *******************************************************/
  617.  
  618. int main() {
  619.  
  620.    int opcion;
  621.  
  622.    while(1) {
  623.  
  624.        imprimirOpciones();
  625.  
  626.        scanf("%d", &opcion);
  627.        //while(getchar() != '\n'); acá debería limpiar el buffer para que no caiga en bucle infinito si se iingresa una letra, pero por algún motivo no me funcionó
  628. correctamente cuando lo utilicé
  629.  
  630.        switch(opcion) {
  631.  
  632.            case 1:
  633.                nuevoContacto();
  634.                break;
  635.            case 2:
  636.                imprimirContactos();
  637.                break;
  638.            case 3:
  639.                imprimirContactosLetra();
  640.                break;
  641.            case 4:
  642.                buscarContactosNombre();
  643.                break;
  644.            case 5:
  645.                buscarContactosTelefono();
  646.                break;
  647.            case 6:
  648.                eliminarContactoNombre();
  649.                break;
  650.            case 7:
  651.                eliminarTodosContactos();
  652.                break;
  653.            case 8:
  654.                liberarMemoria();
  655.                return 0;
  656.            default:
  657.                break;
  658.        }
  659.  
  660.  
  661.    }
  662.  
  663. }
  664.  
  665. /***************************************************************************************************************************
  666.  
  667.     by: Nahuel
  668.  
  669. ***************************************************************************************************************************/


En línea

DarkNicodemus

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Re: Agenda de contactos en C mediante listas enlazadas [Código]
« Respuesta #1 en: 31 Agosto 2016, 08:17 am »

Hola!
Me parece excelente tu programa, but ¿crees que exista la forma de guardar los contactos alfabéticamente en arboles?
Me refiero a que cada nodo, con una letra de asignación (Contactos con la letra, A,B,C, etc)
se guarde en un arbol, todos los contactos con inicio en la letra 'A' se inicia la raíz del árbol con ese nodo :-(


En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Agenda de contactos en C mediante listas enlazadas [Código]
« Respuesta #2 en: 31 Agosto 2016, 18:00 pm »

Se tendría que tener un arreglo de arboles para eso...

Si ya tienes el codigo para un arbol te puedo decir como hacerlo para Cualquier cantidad de arboles.

Saludos!
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Listas enlazadas en c++
Programación C/C++
N3r0 3 8,524 Último mensaje 13 Julio 2010, 12:42 pm
por N3r0
[C] Listas enlazadas.
Programación C/C++
The Swash 5 31,567 Último mensaje 26 Octubre 2011, 04:56 am
por brians444
listas enlazadas
Programación C/C++
javier210186 3 2,837 Último mensaje 25 Octubre 2011, 02:33 am
por javier210186
Problemas con funciones de una agenda con listas enlazadas [C]
Programación C/C++
Rhessus 2 3,278 Último mensaje 15 Julio 2016, 05:02 am
por Rhessus
WhatsApp te permitirá compartir contactos mediante un código QR: así funcionará
Noticias
wolfbcn 0 1,287 Último mensaje 14 Noviembre 2018, 13:43 pm
por wolfbcn
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines