c - 将双向链表保存到 C txt 文件
问题描述
我在下面的 c 中有代码,它将新联系人保存在双向链表中(到目前为止这是有效的),但是,将新联系人保存在 .txt 文件中并查阅它以列出、更改和删除文件,然后再次咨询。
** 有谁知道我如何进行这种同步,我可以定位自己?** 它必须在代码中,我什至不能使用外部库。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct contato {
char nome[50];
char sexo;
int idade;
char fone[15];
char email;
struct contato *ant, *prox;
}Tcontato;
typedef struct indice {
char letra;
struct indice *ant, *prox;
Tcontato *inicio;
}Tindice ;
////Funçoes de Busca////
Tindice * procurarLetra(Tindice * ind, char letra) {
Tindice * aux = ind;
while (aux->letra <= letra) {
if (aux->letra == letra) {
return aux;
}
else if (aux->prox == ind) {
break;
}
else {
aux = aux->prox;
}
}
return NULL;
}
Tcontato * buscaContatoDoIndice(Tcontato *l, char nome[]) {
Tcontato* aux = l;
do {
if (strcmp(nome, aux->nome) == 0) {
return aux;
}
else {
aux = aux->prox;
}
} while (aux != l);
return NULL;
}
Tcontato * busca(Tindice *l, char nome[]) {
char letra = toupper(nome[0]);
Tindice * noIndice;
noIndice = procurarLetra(l, letra);
if (noIndice == NULL) {//N achou o indice da letra
return NULL;
}
else {
return buscaContatoDoIndice(noIndice->inicio, nome);
}
}
/////Funçoes para criar nós////
Tindice * criarLetra(char letra) {
Tindice * novo;
novo = (Tindice *)malloc(sizeof(Tindice));
novo->letra = letra;
novo->ant = NULL;
novo->prox = NULL;
novo->inicio = NULL;
return novo;
}
Tcontato * criarNo(char nome[]) {
Tcontato * novo;
novo = (Tcontato *)malloc(sizeof(Tcontato));
strcpy(novo->nome, nome);
printf("Informe o telefone: ");
gets(novo->fone);
fflush(stdin);
novo->ant = NULL;
novo->prox = NULL;
return novo;
}
/////Funçoes do programa principal////
void cadastrar(Tindice ** l, char nome[]) {
Tindice * noIndice, *novoIndice;
Tcontato *novoNo, * no;
char letra = toupper(nome[0]);
////////agenda vazia/////////
if (*l == NULL) {
novoIndice = criarLetra(letra);//cria o indice
(*l) = novoIndice;
novoIndice->ant = novoIndice;
novoIndice->prox = novoIndice;
novoNo = criarNo(nome);//Criar o NÓ do contato
(*l)->inicio = novoNo;
novoNo->prox = novoNo;
novoNo->ant = novoNo;
printf("Novo contato inserido\n");
}
else {
////////agenda Tem pelo menos uma letra////////
noIndice = procurarLetra(*l, letra);
///////////Indice não existe//////////
if (noIndice == NULL) { //Indice n existe
noIndice = *l;
if (noIndice->letra > letra) {
novoIndice = criarLetra(letra);//cria o indice no inicio
novoIndice->ant = (*l)->ant;
novoIndice->prox = *l;
(*l)->ant->prox = novoIndice;
(*l) = novoIndice;
novoNo = criarNo(nome);//Criar o NÓ do contato no inicio
novoIndice->inicio = novoNo;
novoNo->prox = novoNo;
novoNo->ant = novoNo;
printf("Novo contato inserido\n");
}
else {
do {
if (noIndice->prox->letra > letra) {
novoIndice = criarLetra(letra);//cria o indice no meio
novoIndice->prox = noIndice->prox;
novoIndice->ant = noIndice;
novoIndice->ant->prox = novoIndice;
novoIndice->prox->ant = novoIndice;
novoNo = criarNo(nome);//Criar o NÓ do contato no inicio
novoIndice->inicio = novoNo;
novoNo->prox = novoNo;
novoNo->ant = novoNo;
printf("Novo contato inserido\n");
return;
}
else {
noIndice = noIndice->prox;
}
} while (noIndice != *l);//ACABA o noIndice APONTANDO PARA O PRIMEIRO
novoIndice = criarLetra(letra);//cria o indice no final
novoIndice->prox = noIndice;
novoIndice->ant = noIndice->ant;
noIndice->ant->prox = novoIndice;
noIndice->ant = novoIndice;
novoNo = criarNo(nome);//Criar o NÓ do contato no inicio
novoIndice->inicio = novoNo;
novoNo->prox = novoNo;
novoNo->ant = novoNo;
printf("Novo contato inserido\n");
}
}
///////////Indice ja existe//////////
else {
no = buscaContatoDoIndice(noIndice->inicio, nome);
if (no != NULL) {
printf("Esse contato já existe\n");
}
else {
no = noIndice->inicio;
if (strcmp(no, nome)>0) {//Inserssão no inicio
novoNo = criarNo(nome);//Criar o NÓ do contato no inicio
novoNo->prox = no;
novoNo->ant = no->ant;
no->ant->prox = novoNo;
no->ant = novoNo;
noIndice->inicio = novoNo;
}
else {
do {
if (strcmp(no->prox->nome, nome)>0) { //Inserssão no meio
novoNo = criarNo(nome);//Criar o NÓ do contato no meio
novoNo->prox = no->prox;
novoNo->ant = no;
novoNo->ant->prox = novoNo;
novoNo->prox->ant = novoNo;
printf("Novo contato inserido\n");;
return;
}
else {
no = no->prox;
}
} while (no != noIndice->inicio);//ACABA no APONTANDO PARA O PRIMEIRO
novoNo = criarNo(nome);//Criar o NÓ do contato no final
novoNo->prox = no;
novoNo->ant = no->ant;
no->ant->prox = novoNo;
no->ant = novoNo;
printf("Novo contato inserido\n");;
}
}
}
}
}
void remover(Tindice ** l, char nome[]) {
Tcontato * del;
Tindice * noIndice;
char letra = toupper(nome[0]);
if (*l == NULL) {
printf("Agenda vazia\n");
}
else {
del = busca(*l, nome);
noIndice = procurarLetra(*l, letra);
if (del == NULL) {
printf("Contato não encontrado\n");
}
//Se tiver apenas um nó na determinda letra//
else if (del->prox == del) {//Se tiver apenas um nó na determinda letra
free(del);
//Remover indice da agenda//
if (noIndice->prox == noIndice) {//A agenda só tem uma letra
free(noIndice);
*l = NULL;
printf("Contato Removido\n");
}
else if (noIndice == *l) { //A letra esta no primeiro indice
*l = noIndice->prox;
(*l)->prox = *l;
(*l)->ant = *l;
free(noIndice);
printf("Contato Removido\n");
}
else if (noIndice->prox == *l) {//a letra esta no ultimo indice
(*l)->ant = noIndice->ant;
noIndice->ant->prox = *l;
free(noIndice);
printf("Contato Removido\n");
}
else { //a letra esta no meio
(*l)->prox = noIndice->prox;
noIndice->prox->ant = noIndice->ant;
free(noIndice);
printf("Contato Removido\n");
}
}
//Mais de um nó na determinda letra, n precia desalocar o indice//
else if (noIndice->inicio == del) { //o contato esta no inicio
noIndice->inicio = del->prox;
noIndice->inicio->prox = noIndice->inicio;
noIndice->inicio->ant = noIndice->inicio;
free(del);
printf("Contato Removido\n");
}
else if (del->prox == noIndice->inicio) {//o contato esta no final
noIndice->inicio->ant = del->ant;
del->ant->prox = noIndice->inicio;
free(del);
printf("Contato Removido\n");
}
else { //O contato esta no meio
noIndice->inicio->prox = del->prox;
del->prox->ant = del->ant;
free(del);
printf("Contato Removido\n");
}
}
}
void exibirContato(Tindice *l, char nome[]) {
Tcontato * aux;
if (l == NULL) {
printf("Agenda Vazia\n");
}
else {
aux = busca(l, nome);
if (aux == NULL) {
printf("Contato não encontrado\n");
}
else {
printf("Nome: %s\n", aux->nome);
printf("Telefone: %s\n\n", aux->fone);
}
}
}
void alterarDados(Tindice *l, char nome[]) {
Tcontato * aux;
if (l == NULL) {
printf("Agenda Vazia\n");
}
else {
aux = busca(l, nome);
if (aux == NULL) {
printf("Contato não encontrado\n");
}
else {
printf("Informe o novo telefone: ");
gets(aux->fone);
fflush(stdin);
printf("Telefone alterado\n");
}
}
}
void exibirTudo(Tindice *l) {
Tindice * i;
Tcontato * x;
if (l == NULL) {
printf("Agenda vazia\n");
}
else {
i = l;
do {//Caminha nos indices
x = i->inicio;
do//Caminha nos nós dos contatos
{
printf("Nome: %s\n", x->nome);
printf("Telefone: %s\n\n", x->fone);
x = x->prox;
} while (x != i->inicio);
i = i->prox;
} while (i != l);
}
}
void exibirLetra(Tindice *l, char letra) {
Tindice * noIndice;
Tcontato * aux;
char let = toupper(letra);
if (l == NULL) {
printf("Agenda Vazia\n");
}
else {
noIndice = procurarLetra(l, let);
if (noIndice == NULL) {
printf("Letra não encontrada\n");
}
else {
aux = noIndice->inicio;
do {
printf("Nome: %s\n", aux->nome);
printf("Telefone: %s\n\n", aux->fone);
aux = aux->prox;
} while (aux != noIndice->inicio);
}
}
}
void removerTudo(Tindice ** l) {
if (l == NULL) {
printf("Agenda vazia\n");
}
}
int main() {
Tindice * agenda = NULL;
char nome[100], op, fone[100], letra;
do {
printf("\t\tEscolha uma opção\n\n");
printf("1 - Inserir novo contato\n");
printf("2 - Remover contato\n");
printf("3 - Exibir um contato\n");
printf("4 - Alterar telefone\n");
printf("5 - Exibir toda agenda\n");
printf("6 - Exibir os contatos de uma letra \n");
printf("7 - Sair do Programa\n");
op = getche();
printf("\n");
fflush(stdin);
printf("\n");
switch (op) {
case '1':printf("Informe o nome do novo contato:");
gets(nome);
fflush(stdin);
cadastrar(&agenda, nome);
break;
case '2':printf("Informe o nome do contato que deseja remover:");
gets(nome);
fflush(stdin);
remover(&agenda, nome);
break;
case '3':printf("Informe o nome do contato que deseja exibir:");
gets(nome);
fflush(stdin);
exibirContato(agenda, nome);
break;
case '4':printf("Informe o nome do contato que deseja alterar:");
gets(nome);
fflush(stdin);
alterarDados(agenda, nome);
break;
case '5':exibirTudo(agenda);
break;
case '6':printf("Informe a letra:");
scanf("%c", &letra);
fflush(stdin);
exibirLetra(agenda, letra);
break;
case '7':removerTudo(agenda);
break;
default: printf("Opcao Invalida \n");
}
} while (op != '7');
return 0;
}
解决方案
对于链表的保存和加载问题,我建议大家首先关注如何保存和加载链表中的单个节点,作为文件中的单个“记录”。没有链接。将它们放在单独的函数中。
一旦你的代码工作了,扩展它来保存或加载一个列表实际上是非常简单的。
为了保存,只需为列表中的每个节点调用“保存”函数。文件中记录的顺序是列表。
要读取列表,一次读取一条记录,将每条记录附加到列表的后面。从文件中读取所有记录后,您就拥有了列表。
推荐阅读
- javascript - 在客户端进行firebase电话身份验证并在服务器的数据库中创建帐户的最佳方法
- service - 如何使用 systemd 启动 pyqt ui 应用程序
- flutter - 使用 VS Code 发布 Flutter 的应用程序
- python - 涉及 javascript 元素的 Python Web Scraping
- c++ - 如何仅使用对象名称打印对象特定成员?
- html - 如何在 html 中实现我感到幸运?
- python - 在 python 中理解 Twitter Premium API 沙盒
- azure - Connect-MSGraph 命令无法在 Azure Functions powershell core 6 中执行
- python-3.x - keras 中的强化学习问题不学习
- mysql - 如何在仅返回一次州和城市名称的同时返回与州和城市关联的每条记录?(MySql)