PROGRAMA CADASTRO LISTAPOSTA.C NÃO GRAVA NO ARQUIVO .TXT

1. PROGRAMA CADASTRO LISTAPOSTA.C NÃO GRAVA NO ARQUIVO .TXT

Jonny Ernani Maia
jonnycicuto

(usa Ubuntu)

Enviado em 23/05/2021 - 20:25h

Senhor professores,
O meu programa acima é um cadastro de pessoas que quero gravar em um arquivo (.txt). compilado no DEV
ocorre que quando chamo o arquivo (fopen), ele não consegue GRAVAR no arquivo chamado. (c:\\User\\jonny\\Documentos\\dados.txt)
Em anexo segue o arquivo, icarei imensamente grato se resolverem mais este programa em C. Ele gerra arquivo inexistente.

Muito obrigado

jonny cicuto
#include <stdio.h> 
#include <ctype.h> // Para toupper
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//#include <stdio_ext.h> // Para __fpurge
//#ifndef _STDIO_EXT_H
#define _STDIO_EXT_H

#define MAX 100

#define LISTA_TELA 0
#define LISTA_ARQUIVO 1

// Variavel que indica se a lista foi modificada e nao salva
int nao_salvo = 0;

struct addr {
char name [30];
char street[40];
char city [20];
char state [3];
long zip;
} *addr_info;

// Funcao para leitura de uma string de tamanho n
void LerString(char *txt, int n)
{
// Descarrega o buffer e faz a leitura de string
// __fpurge(stdin);
fgets(txt, n, stdin);

// Procura por quebras de linha, espacos ou tab no final da string, removendo-os
n = strlen(txt) - 1;
while(txt[n] == '\n' || txt[n] == '\r' || txt[n] == ' ' || txt[n] == '\t')
txt[n--] = 0;
}

// Funcao para validar uma string como CEP. Retorna o cep ou -1 se invalido
long ValidaCEP(char *cep)
{
int i;

// Para ser um cep, a string deve conter 8 (se nao fornecido o hifen) ou 9 caracteres.
if(strlen(cep) == 9 && cep[5] == '-') {
// CEP com hifen. Vamos remove-lo.
for(i=5; i<9; i++) {
cep[i] = cep[i+1];
}
} else if(strlen(cep) != 8) {
return -1; // CEP invalido
}

// Verifica se todos os caracteres sao numericos
for(i=0; i<8; i++) {
if(cep[i] < '0' || cep[i] > '9')
return -1; // Encontrado caracter nao numerico, cep invalido.
}

// Se o programa chegou ate aqui, indica que temos um cep valido. Basta retornarmos o cep convertido para long int
return atol(cep);
}

void CarregaCEP(char *cep_txt, int cep_num)
{
int cep_alto, cep_baixo;

cep_alto = cep_num/1000;
cep_baixo = cep_num - (cep_alto*1000);

sprintf(cep_txt, "%05d-%03d", cep_alto, cep_baixo);
}

//Otem a seleção
int menu_select(void)
{
char s[80];

printf("1. Inserir um nome\n\n");
printf("2. Excluir um nome \n\n");
printf("3. Listar o arquivo \n\n");
printf("4. Salvar Registros\n\n");
printf("5. Exportar como Texto\n\n");
printf("6. Sair\n\n");

printf("Digite sua escolha:____");
LerString(s, sizeof(s));
return atoi(s);
}

//Encontra um estrutura não usada
int find_free(void)
{
int t;

for(t=0;addr_info[t].name[0] && t<MAX; t++);

if(t==MAX)
return -1; //nenyhum elemento livre

return t;
}

//Insere os endereços na lista.
void enter(void)
{
int slot;
char s[80];

slot = find_free();
if(slot==-1) {
printf("Lista cheia\n\n");
return;
}

nao_salvo = 1;

printf("Digite o nome: \n\n");
LerString(addr_info[slot].name, sizeof(addr_info[slot].name));
printf("Digite a rua: \n\n");
LerString(addr_info[slot].street, sizeof(addr_info[slot].street));
printf("Digite a cidade: \n\n");
LerString(addr_info[slot].city, sizeof(addr_info[slot].city));
printf("Digite o Estado: \n\n");
LerString(addr_info[slot].state, sizeof(addr_info[slot].state));
do {
printf("Digite o CEP: \n\n");
LerString(s, sizeof(s));
addr_info[slot].zip = ValidaCEP(s);

if(addr_info[slot].zip < 0) {
printf("CEP invalido!\n");
}
} while(addr_info[slot].zip < 0);
}

int procura(char *nome)
{
int t;

for(t=0; t < MAX; t++){
if(!strcmp(nome, addr_info[t].name))
return t;
}

return -1;
}

//Apaga um endereço
void delete(void)
{
int slot;
char s[80];

printf(" Digite o registro #:\n\n");
LerString(s, sizeof(s));
slot = atoi(s);
if(slot>=0 && slot < MAX) {
addr_info[slot].name[0]= 0;
nao_salvo = 1;
}
}

//Mostra lista na tela
void list(int tipo)
{
int t;
FILE *saida;
char txt[10];

if(tipo == LISTA_TELA) {
saida = stdout;
} else {
saida = fopen("dados.txt", "w");
if(saida == NULL) {
printf("Erro abrindo arquivo!\n");
}
}

for(t=0; t<MAX; ++t){
if(addr_info[t].name[0]){
fprintf(saida, "---------------------------------\n");
fprintf(saida, "Registro %d\n", t);
fprintf(saida, "%s \n", addr_info[t].name);
fprintf(saida, "%s \n", addr_info[t].street);
fprintf(saida, "%s \n", addr_info[t].city);
fprintf(saida, "%s \n", addr_info[t].state);
CarregaCEP(txt, addr_info[t].zip);
fprintf(saida, "%s \n", txt);

if(tipo==LISTA_TELA && t && !(t%5))
sleep(4);
}
}

fprintf(saida, "\n\n");

if(tipo == LISTA_ARQUIVO) {
fclose(saida);
}
}

int salva(void){
FILE *dadosHd;

dadosHd = fopen("dados.txt", "wb");

fwrite(addr_info, sizeof(struct addr), MAX, dadosHd);
fclose(dadosHd);

nao_salvo = 0;

return 0;
}

void inicia(void){
FILE *dadosHd;

addr_info = malloc(sizeof(struct addr) * MAX);

dadosHd = fopen("C:\\Users\\jonny\\Documentos\\dados.txt", "wb");

if(dadosHd != NULL) {
fread(addr_info, sizeof(struct addr), MAX, dadosHd);


printf("%d ------------------<\n", sizeof(struct addr));
printf("nome - %s\n", addr_info[0].name);

fclose(dadosHd);
} else {
memset(addr_info, 0, sizeof(struct addr) * MAX);
printf("Arquivo inexistente\n");
}
}

int main(void)
{
char choice;

inicia();

printf("Legal heim\n\n\n");

for(;;) {
choice=menu_select();
switch(choice) {
case 1: enter();
break;

case 2: delete();
break;

case 3: list(LISTA_TELA);
break;

case 4: salva();
break;
case 5: list(LISTA_ARQUIVO);
break;

case 6:
if(nao_salvo) {
printf("Lista nao salva desde a ultima modificacao! Sair mesmo assim? (S/N): ");
if(toupper(getchar()) != 'S') // Nao confirmou, continuar o programa.
break;
}
exit(0);
break;

default:
printf("Opcao invalida!\n");

}
}
}



  


2. Re: PROGRAMA CADASTRO LISTAPOSTA.C NÃO GRAVA NO ARQUIVO .TXT

Paulo
paulo1205

(usa Ubuntu)

Enviado em 23/05/2021 - 23:21h

“Problema” de Windows.

O caminho "%HOMEDRIVE%%HOMEPATH%\Documentos" não existe, mesmo no Windows em Português (tipicamente o valor de HOMEDRIVE é “C:” e o de HOMEPATH é “\Users\seu_login”). O Windows Explorer e outros componentes na interface gráfica até apresentam alguns nomes traduzidos, mas o caminho real dentro do sistema operacional, que é o que o programa em C enxerga, não depende do idioma, e é sempre Documents.

Tente trocar no seu programa e veja se funciona. Mas você também pode confirmar isso abrindo um Prompt de Comando ou uma sessão de Powershell e navegando pelo sistema de Arquivos.


... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


3. PROGRAMA CADASTRO DEV 4.9.9.2

Jonny Ernani Maia
jonnycicuto

(usa Ubuntu)

Enviado em 24/05/2021 - 15:31h

Professor Paulo1205, agradeço imensamente o seu esforço, muito obrigado, do coração. Professor é seguinte eu estou programando no WINDOWS 7, DEV 4.9.9.2.
O que ocorre é o seguinte: o programa acima cadastro, ele cria um arquivo no diretorio c:\\Users\\jonny\\Documents\\dados.txt da mesma forma quando, eu crio em
c:\\dados.txt, veja, professor ele CRIA o arquivo, mas não REGISTRA NADA neste arquivos como:
- como nome:
- endereço:
- cidade:
- Estado:
- CEP;
Esses dados ficam temporariamente na tela, mas não registra no BLOCO DE NOTAS arquivo dados.txt , não sei se é problema de permissão no windows 7, sei que é um problema do S.O.
Estou tentando de tudo quanto é forma para gravar no BLOCO DE NOTAS (WINDOWS 7), no arquivo dados.txt e não consigo. Preciso da sua ajuda, pois estou trabalhando no WINDOOWS 7 ,
ambiente de programação DEV4.9.9.2
Até o momento agradeço a sua valiosa atenção comigo. Peço ajuda mais uma vez, NÃO CONDIGO GRAVAR NO BLOCO DE NOTAS no arquivo: dados.txt.
professor muito obrigado do coração. VIVA O LINUX, e parabem a todos voces.

Jonnycicuto fone 41 991861492

#include <stdio.h> 
#include <ctype.h> // Para toupper
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//#include <stdio_ext.h> // Para __fpurge //
//#ifndef _STDIO_EXT_H
#define _STDIO_EXT_H

#define MAX 2

#define LISTA_TELA 0
#define LISTA_ARQUIVO 1

// Variavel que indica se a lista foi modificada e nao salva
int nao_salvo = 0;

struct addr {
char name [30];
char street[40];
char city [20];
char state [3];
long zip;
} *addr_info;

// Funcao para leitura de uma string de tamanho n
void LerString(char *txt, int n)
{
// Descarrega o buffer e faz a leitura de string
// __fpurge(stdin);
fgets(txt, n, stdin);

// Procura por quebras de linha, espacos ou tab no final da string, removendo-os
n = strlen(txt) - 1;
while(txt[n] == '\n' || txt[n] == '\r' || txt[n] == ' ' || txt[n] == '\t')
txt[n--] = 0;
}

// Funcao para validar uma string como CEP. Retorna o cep ou -1 se invalido
long ValidaCEP(char *cep)
{
int i;

// Para ser um cep, a string deve conter 8 (se nao fornecido o hifen) ou 9 caracteres.
if(strlen(cep) == 9 && cep[5] == '-') {
// CEP com hifen. Vamos remove-lo.
for(i=5; i<9; i++) {
cep[i] = cep[i+1];
}
} else if(strlen(cep) != 8) {
return -1; // CEP invalido
}

// Verifica se todos os caracteres sao numericos
for(i=0; i<8; i++) {
if(cep[i] < '0' || cep[i] > '9')
return -1; // Encontrado caracter nao numerico, cep invalido.
}

// Se o programa chegou ate aqui, indica que temos um cep valido. Basta retornarmos o cep convertido para long int
return atol(cep);
}

void CarregaCEP(char *cep_txt, int cep_num)
{
int cep_alto, cep_baixo;

cep_alto = cep_num/1000;
cep_baixo = cep_num - (cep_alto*1000);

sprintf(cep_txt, "%05d-%03d", cep_alto, cep_baixo);
}

//Otem a seleção
int menu_select(void)
{
char s[80];

printf("1. Inserir um nome\n\n");
printf("2. Excluir um nome \n\n");
printf("3. Listar o arquivo \n\n");
printf("4. Salvar Registros\n\n");
printf("5. Exportar como Texto\n\n");
printf("6. Sair\n\n");

printf("Digite sua escolha:____");
LerString(s, sizeof(s));
return atoi(s);
}

//Encontra um estrutura não usada
int find_free(void)
{
int t;

for(t=0;addr_info[t].name[0] && t<MAX; t++);

if(t==MAX)
return -1; //nenyhum elemento livre

return t;
}

//Insere os endereços na lista.
void enter(void)
{
int slot;
char s[80];

slot = find_free();
if(slot==-1) {
printf("Lista cheia\n\n");
return;
}

nao_salvo = 1;

printf("Digite o nome: \n\n");
LerString(addr_info[slot].name, sizeof(addr_info[slot].name));
printf("Digite a rua: \n\n");
LerString(addr_info[slot].street, sizeof(addr_info[slot].street));
printf("Digite a cidade: \n\n");
LerString(addr_info[slot].city, sizeof(addr_info[slot].city));
printf("Digite o Estado: \n\n");
LerString(addr_info[slot].state, sizeof(addr_info[slot].state));
do {
printf("Digite o CEP: \n\n");
LerString(s, sizeof(s));
addr_info[slot].zip = ValidaCEP(s);

if(addr_info[slot].zip < 0) {
printf("CEP invalido!\n");
}
} while(addr_info[slot].zip < 0);
}

int procura(char *nome)
{
int t;

for(t=0; t < MAX; t++){
if(!strcmp(nome, addr_info[t].name))
return t;
}

return -1;
}

//Apaga um endereço
void delete(void)
{
int slot;
char s[80];

printf(" Digite o registro #:\n\n");
LerString(s, sizeof(s));
slot = atoi(s);
if(slot>=0 && slot < MAX) {
addr_info[slot].name[0]= 0;
nao_salvo = 1;
}
}

//Mostra lista na tela
void list(int tipo)
{
int t;
FILE *saida;
char txt[10];

if(tipo == LISTA_TELA) {
saida = stdout;
} else {
saida = fopen("C:\\furunda.txt", "w");
if(saida == NULL) {
printf("Erro abrindo arquivo!\n");
}
}

for(t=0; t<MAX; ++t){
if(addr_info[t].name[0]){
fprintf(saida, "---------------------------------\n");
fprintf(saida, "Registro %d\n", t);
fprintf(saida, "%s \n", addr_info[t].name);
fprintf(saida, "%s \n", addr_info[t].street);
fprintf(saida, "%s \n", addr_info[t].city);
fprintf(saida, "%s \n", addr_info[t].state);
CarregaCEP(txt, addr_info[t].zip);
fprintf(saida, "%s \n", txt);

if(tipo==LISTA_TELA && t && !(t%5))
sleep(4);
}
}

fprintf(saida, "\n\n");

if(tipo == LISTA_ARQUIVO) {
fclose(saida);
}
}

int salva(void){
FILE *dadosHd;

dadosHd = fopen("C:\\dados.txt", "w");

fwrite(addr_info, sizeof(struct addr), MAX, dadosHd);
scanf("%s",dadosHd);

fprintf(dadosHd,"s",dadosHd);

fclose(dadosHd);

nao_salvo = 0;

return 0;
}

void inicia(void){
FILE *dadosHd;

addr_info = malloc(sizeof(struct addr) * MAX);

dadosHd = fopen("C:\\dados.txt", "w");

if(dadosHd != NULL) {
fread(addr_info, sizeof(struct addr), MAX, dadosHd);


printf("%d ------------------<\n", sizeof(struct addr));
printf("nome - %s\n", addr_info[0].name);

fclose(dadosHd);
} else {
memset(addr_info, 0, sizeof(struct addr) * MAX);
printf("Arquivo inexistente\n");
}
}

int main(void)
{
char choice;

inicia();

printf("Legal heim\n\n\n");

for(;;) {
choice=menu_select();
switch(choice) {
case 1: enter();
break;

case 2: delete();
break;

case 3: list(LISTA_TELA);
break;

case 4: salva();
break;
case 5: list(LISTA_ARQUIVO);
break;

case 6:
if(nao_salvo) {
printf("Lista nao salva desde a ultima modificacao! Sair mesmo assim? (S/N): ");
if(toupper(getchar()) != 'S') // Nao confirmou, continuar o programa.
break;
}
exit(0);
break;

default:
printf("Opcao invalida!\n");

}
}
}



4. Re: PROGRAMA CADASTRO LISTAPOSTA.C NÃO GRAVA NO ARQUIVO .TXT

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/05/2021 - 01:09h

jonnycicuto escreveu:

Professor Paulo1205, agradeço imensamente o seu esforço, muito obrigado, do coração. Professor é seguinte eu estou programando no WINDOWS 7, DEV 4.9.9.2.


Não sou professor. Sou um colega de fórum que tenta ajudar na medida de seus parcos conhecimentos.

O que ocorre é o seguinte: o programa acima cadastro, ele cria um arquivo no diretorio c:\\Users\\jonny\\Documents\\dados.txt da mesma forma quando, eu crio em
c:\\dados.txt, veja, professor ele CRIA o arquivo, mas não REGISTRA NADA neste arquivos como:
- como nome:
- endereço:
- cidade:
- Estado:
- CEP;
Esses dados ficam temporariamente na tela, mas não registra no BLOCO DE NOTAS arquivo dados.txt , não sei se é problema de permissão no windows 7, sei que é um problema do S.O.


Em sua postagem anterior, você disse que a mensagem de erro era de arquivo inexistente. Então a mensagem era do Notepad, e não do seu programa? Isso não ficou claro, pois você nem ao menos mencionou tentativa de abrir o arquivo com um programa externo.

Estou tentando de tudo quanto é forma para gravar no BLOCO DE NOTAS (WINDOWS 7), no arquivo dados.txt e não consigo. Preciso da sua ajuda, pois estou trabalhando no WINDOOWS 7 ,
ambiente de programação DEV4.9.9.2


Gravar no Bloco de Notas, ou gravar num arquivo que ele consiga abrir? É importante que você deixe isso claro.

#include <stdio.h> 
#include <ctype.h> // Para toupper
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//#include <stdio_ext.h> // Para __fpurge //
//#ifndef _STDIO_EXT_H
#define _STDIO_EXT_H

#define MAX 2

#define LISTA_TELA 0
#define LISTA_ARQUIVO 1

// Variavel que indica se a lista foi modificada e nao salva
int nao_salvo = 0;

struct addr {
char name [30];
char street[40];
char city [20];
char state [3];
long zip;
} *addr_info;
[/quote]

Aqui você usou long para o tipo do CEP, mas em outros lugares usou int. Mesmo que esses dois tipos tenham a mesma representação interna na sua máquina (o que era comum em PCs de 32 bits, mas não o é nos de 64 bits), é melhor ser mais coerente, e escolher apenas um deles, e usar o mesmo tipo ao longo de todo o programa.

Mas eu sugeriria não utilizar nenhum desses dois. Como o CEP nunca será negativo, sugiro usar um tipo sem sinal e de tamanho que nunca depende de arquitetura. Nesse sentido, eu preferiria usar uint32_t (definido em <stdint.h> como um inteiro sem sinal com exatamente 32 bits de tamanho). E onde você antes usou -1 como valor inválido de CEP, poderia usar 0, já que o CEP não prevê nenhum valor abaixo de 01000-000 (que, na conversão que você usou, valeria um milhão). Usar zero como valor inválido tem uma vantagem adicional, já que zero também é o valor de condição booleana falsa em C.


// Funcao para leitura de uma string de tamanho n
void LerString(char *txt, int n)
''{
// Descarrega o buffer e faz a leitura de string
// __fpurge(stdin);
fgets(txt, n, stdin);

// Procura por quebras de linha, espacos ou tab no final da string, removendo-os
n = strlen(txt) - 1;
while(txt[n] == '\n' || txt[n] == '\r' || txt[n] == ' ' || txt[n] == '\t')
txt[n--] = 0;
}


O que você acha que acontece com a função acima se a pessoa digitar uma linha vazia (i.e. apenas apertar a tecla «Enter»)?

Você que de garantir que n nunca seja negativo.

Já que você criou uma função específica para ler suas linhas de texto, seria interessante você garantir que a linha lida não excedeu o tamanho máximo do buffer de leitura ou que, se o tiver excedido (i.e. mais do que n-1 caracteres antes do «Enter»), garantir que os caracteres em excesso não prejudiquem leituras seguintes.


// Funcao para validar uma string como CEP. Retorna o cep ou -1 se invalido
long ValidaCEP(char *cep)
{
int i;

// Para ser um cep, a string deve conter 8 (se nao fornecido o hifen) ou 9 caracteres.
if(strlen(cep) == 9 && cep[5] == '-') {
// CEP com hifen. Vamos remove-lo.
for(i=5; i<9; i++) {
cep[i] = cep[i+1];
}
} else if(strlen(cep) != 8) {
return -1; // CEP invalido
}

// Verifica se todos os caracteres sao numericos
for(i=0; i<8; i++) {
if(cep[i] < '0' || cep[i] > '9')
return -1; // Encontrado caracter nao numerico, cep invalido.
}

// Se o programa chegou ate aqui, indica que temos um cep valido. Basta retornarmos o cep convertido para long int
return atol(cep);
}


Eu acho que daria para validar o CEP e converter para um tipo inteiro com menos esforço da sua parte. Pensei na seguinte forma.
unsigned cep_princ, cep_sub;
int a=0, b=0, c=0, d=0; // Usados para medir a quantidade de caracteres consumidos (pseudo-conversão “%n”).
return
(
sscanf(cep, " %n%5u%n - %n%3u%n", &a, &cep_princ, &b, &c, &cep_sub, &d)==2 &&
b>a /* ou “b-a==5“ */ && c>b && d>c /* ou “d-c==3” */
)? 1000u*cep_princ+cep_sub: 0 /* Já supondo 0 como valor de CEP inválido, como eu propus, acima. */
;

)


void CarregaCEP(char *cep_txt, int cep_num)
{
int cep_alto, cep_baixo;

cep_alto = cep_num/1000;
cep_baixo = cep_num - (cep_alto*1000);

sprintf(cep_txt, "%05d-%03d", cep_alto, cep_baixo);
}

//Otem a seleção
int menu_select(void)
{
char s[80];

printf("1. Inserir um nome\n\n");
printf("2. Excluir um nome \n\n");
printf("3. Listar o arquivo \n\n");
printf("4. Salvar Registros\n\n");
printf("5. Exportar como Texto\n\n");
printf("6. Sair\n\n");

printf("Digite sua escolha:____");
LerString(s, sizeof(s));
return atoi(s);
}

//Encontra um estrutura não usada
int find_free(void)
{
int t;

for(t=0;addr_info[t].name[0] && t<MAX; t++);

if(t==MAX)
return -1; //nenyhum elemento livre

return t;
}

//Insere os endereços na lista.
void enter(void)
{
int slot;
char s[80];

slot = find_free();
if(slot==-1) {
printf("Lista cheia\n\n");
return;
}

nao_salvo = 1;

printf("Digite o nome: \n\n");
LerString(addr_info[slot].name, sizeof(addr_info[slot].name));
printf("Digite a rua: \n\n");
LerString(addr_info[slot].street, sizeof(addr_info[slot].street));
printf("Digite a cidade: \n\n");
LerString(addr_info[slot].city, sizeof(addr_info[slot].city));
printf("Digite o Estado: \n\n");
LerString(addr_info[slot].state, sizeof(addr_info[slot].state));
do {
printf("Digite o CEP: \n\n");
LerString(s, sizeof(s));
addr_info[slot].zip = ValidaCEP(s);

if(addr_info[slot].zip < 0) {
printf("CEP invalido!\n");
}
} while(addr_info[slot].zip < 0);
}

int procura(char *nome)
{
int t;

for(t=0; t < MAX; t++){
if(!strcmp(nome, addr_info[t].name))
return t;
}

return -1;
}

//Apaga um endereço
void delete(void)
{
int slot;
char s[80];

printf(" Digite o registro #:\n\n");
LerString(s, sizeof(s));
slot = atoi(s);
if(slot>=0 && slot < MAX) {
addr_info[slot].name[0]= 0;
nao_salvo = 1;
}
}

//Mostra lista na tela
void list(int tipo)
{
int t;
FILE *saida;
char txt[10];

if(tipo == LISTA_TELA) {
saida = stdout;
} else {
saida = fopen("C:\\furunda.txt", "w");
if(saida == NULL) {
printf("Erro abrindo arquivo!\n");


Em lugar de apenas imprimir o erro e continuar, seria mais prudente imprimir o erro e sair da função, já que nada mais abaixo fará sentido se o valor de saida não for válido.

Além disso, o C normalmente oferece canais separados para saída normal do programa (stdout) e saída de mensagens de erro (stderr).

Outra sugestão, mas não tão importante, seria indicar ao usuário a causa raiz do erro, que você pode saber através da variável global errno (em <errno.h>) e traduzir em mensagem humanamente legível com a função strerror() (em <string.h>).

Juntando essas sugestões, creio que sua rotina de tratamento de erros poderia ficar mais parecida com o seguinte.
if(!saida){
int ch;
fprintf(stderr, "Erro ao abrir arquivo: %s.\n", strerror(errno));
puts("Tecle <Enter> para retornar.");
while((ch=getchar())!=EOF && ch"='\n')
;
return;
}


		} 
}

for(t=0; t<MAX; ++t){
if(addr_info[t].name[0]){
fprintf(saida, "---------------------------------\n");
fprintf(saida, "Registro %d\n", t);
fprintf(saida, "%s \n", addr_info[t].name);
fprintf(saida, "%s \n", addr_info[t].street);
fprintf(saida, "%s \n", addr_info[t].city);
fprintf(saida, "%s \n", addr_info[t].state);
CarregaCEP(txt, addr_info[t].zip);
fprintf(saida, "%s \n", txt);

if(tipo==LISTA_TELA && t && !(t%5))
sleep(4);
}
}

fprintf(saida, "\n\n");

if(tipo == LISTA_ARQUIVO) {
fclose(saida);
}
}

int salva(void){
FILE *dadosHd;

dadosHd = fopen("C:\\dados.txt", "w");


Aqui convém testar se a abertura do arquivo foi bem feita antes de começar a gravar, tal como foi mostrado anteriormente.


fwrite(addr_info, sizeof(struct addr), MAX, dadosHd);
scanf("%s",dadosHd);

fprintf(dadosHd,"s",dadosHd);

fclose(dadosHd);

nao_salvo = 0;

return 0;
}

void inicia(void){
FILE *dadosHd;

addr_info = malloc(sizeof(struct addr) * MAX);

dadosHd = fopen("C:\\dados.txt", "w");


Se você quer ler um arquivo preexistente, não deve nunca usar w no modo de abertura (segundo parâmetro de fopen()). Usar w provoca o truncamento de qualquer conteúdo previamente existente no arquivo. Provavelmente você quis usar o modo r, que faz com que um arquivo preexistente seja aberto para leitura.


if(dadosHd != NULL) {
fread(addr_info, sizeof(struct addr), MAX, dadosHd);


printf("%d ------------------<\n", sizeof(struct addr));
printf("nome - %s\n", addr_info[0].name);

fclose(dadosHd);
} else {
memset(addr_info, 0, sizeof(struct addr) * MAX);
printf("Arquivo inexistente\n");
}
}

int main(void)
{
char choice;

inicia();

printf("Legal heim\n\n\n");

for(;;) {
choice=menu_select();
switch(choice) {
case 1: enter();
break;

case 2: delete();
break;

case 3: list(LISTA_TELA);
break;

case 4: salva();
break;
case 5: list(LISTA_ARQUIVO);
break;

case 6:
if(nao_salvo) {
printf("Lista nao salva desde a ultima modificacao! Sair mesmo assim? (S/N): ");
if(toupper(getchar()) != 'S') // Nao confirmou, continuar o programa.
break;


Sugiro usar uma verificação um pouco mais robusta, uma vez que getchar() pode falhar e, nesse caso, você provavelmente gostaria, sim, de encerrar o programa também.

				} 
exit(0);
break;

default:
printf("Opcao invalida!\n");

}
}
}




... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)