leer/modificar/escribir archivos de texto

Iniciado por Neibar, 5 Abril 2012, 00:46 AM

0 Miembros y 1 Visitante están viendo este tema.

Neibar

Hola gente, a ver si me podeis orientar un pelín con un problemilla que tengo con este intento de programa. Se supone que es un listin telefonico (guardado en .txt), el cual el usuario puede ver el contenido, añadir nuevos numeros/nombres, borrarlos...

Mi problema está en el hecho de que, tengo 2 arrays (uno para nombres, otro para los numeros), y los rellené haciendo pruebas... y ahora el de los numeros no hay manera alguna de borrarle el contenido. A su vez, el de nombres sigue yendo bien.

Solo necesito una orientación de cómo puedo hacer que se borre el contenido. Ya probé de inicializarlo a 0, y nada.

Os dejo el código y si a alguien se le ocurre dónde está el error... en cuanto a las funciones, solo puedo usar : fscanf, fopen, fclose, feof

(he traducido al castellano lo que he podido, ya que lo tenia en catalan)

Gracias de antemano


#include <stdio.h>
#include <iostream>

int main (){
bool sortir=false; // bolea, controla sortida 5


while(!sortir){ //bucle , sortida seleccio 1 - 5
int seleccio;

bool ok_seleccio=false; //boolea per controlar letras

//while(!ok_seleccio){ //controla que sean numeros

printf("\n********************\n");
printf("Menu ");
printf("\n********************\n");
printf("1.Introducir nuevo telefono \n2.Buscar por nombre  \n3.Guardar en disco \n4.Cargar listado  \n5.Salir\n\nSeleccion: ");
scanf("%d",&seleccio);

bool in_sortir=false; //boolea case 2
FILE *fp;
int espais=1;

//case 1, guarda numero i nom de contacte , variables
int afegir=0;
int numero[10];
char contacte[10];

switch(seleccio){
                       
                case 1:        
                     printf("Introduce el numero : ");
                     scanf("%d", &numero[afegir]);
                     
                     printf("Introduce el nombre del contacto : ");
                     scanf("%s", &contacte[afegir]);
                     afegir++;
                     
                     break;
                case 2:
                     while(!in_sortir){
                         char nom[15];
                         printf("Introduce el nombre : ");
                         scanf("%s",&nom);
                         //... falta desarrollar ...

                         
                         
                     }
                     
                     break;
                case 3:
                     afegir = afegir -1;
                     printf("Guardando cambios....");
                     fp=fopen("telefons.txt","a");
                     fprintf(fp,"%s %d\n" ,contacte,numero);          
                     printf("\nTots els canvis han sigut guardats");
                     fclose(fp);
                     for (int i=0;i<10;i++){ contacte[i]=0; numero[i]=0; }
                     break;
                case 4:
                     
                     printf("Carregant llisti telefonic...\n");
                     fp = fopen("telefons.txt","r");
                     
                     char content[20];
                     while(!feof(fp)){
                             fscanf (fp, "%s", &content);
                              printf("\n%s ", content);
                              espais++;
                              if(espais==2){ printf("\n"); espais=0;}
                     }
                     fclose(fp);
                     
                     break;
                case 5:
                     printf("Saliendo del programa...");
                     sortir=true;
                     break;
                default:
                        if(seleccio<0 || seleccio>6){
                              printf("error en la seleccion, las opciones son del 1 al 5");
                         }
                         break;
               
}
}
system("PAUSE");
   
return 0;  
}

Xandrete

¡Vaya, comentarios en catalán! Quina sorpresa més agradable!

A ver, me gustaría comentarte unas cosillas primero. Si estás programando en C++, has de tener en cuenta que has de incluir la librería cstdio, no stdio.h.

Por otro lado, no es necesario incluir la biblioteca iostream ya que no utilizas nada de ella.

¿Qué quieres decir con borrar exactamente? Permíteme copiarte el case 3 del bloque switch:

Código (cpp) [Seleccionar]
                      afegir = afegir -1;
                      printf("Guardando cambios....");
                      fp=fopen("telefons.txt","a");
                      fprintf(fp,"%s %d\n" ,contacte,numero);         
                      printf("\nTots els canvis han sigut guardats");
                      fclose(fp);
                      for (int i=0;i<10;i++){ contacte[i]=0; numero[i]=0; }
                      break;


Lo que haces es:

- Decrementar el indicador de posición afegir.
- Guardar en el documento el nombre del contacto seguido de... un puntero Si pones "numero" a secas, ¡estás imprimiendo un puntero en el documento! De hecho, estás imprimiendo el puntero a la primera posición del array numero.
- Poner todas las posiciones de los arrays contacte y numero a 0. Mi pregunta es: ¿por qué guardas 10 números en un array si sólo vas a coger el último y el resto los borras?

Además, si borras todos los números, ¡deberías darle el valor 0 a afegir!

También es curioso el tratamiento que haces del array de caracteres contacte. A veces lo tratar como una cadena de texto (como en la sección de código anterior) y otras lo tratas como un vector de cadenas de texto, como en el siguiente fragmento:

Código (cpp) [Seleccionar]
                      printf("Introduce el numero : ");
                      scanf("%d", &numero[afegir]);
                     
                      printf("Introduce el nombre del contacto : ");
                      scanf("%s", &contacte[afegir]);
                      afegir++;
                     
                      break;


A no ser que los nombres tengan siempre longitud máxima de un carácter, deberías revisar esto.

¡Saludos!

durasno

Hola!  Xandrete tiene razon.... Lo que vos queres es tener 10 numero de telefono y 10 nombres de contactos, ahora ¿como haces para tenes 10 nombres en un arreglo que tiene una longitud de 10 char? una solucion seria utilizar un arreglo de punteros, aunque seria mas conveniente, si es q conoces, usar un arreglo de estructuras donde tu estructura seria:
struct contacto {
  int numero;
  char contacte[10];
};

Saludos
Ahorrate una pregunta, lee el man

Neibar

#3
Cita de: Xandrete en  5 Abril 2012, 01:39 AM
Si estás programando en C++, has de tener en cuenta que has de incluir la librería cstdio, no stdio.h.

Por otro lado, no es necesario incluir la biblioteca iostream ya que no utilizas nada de ella.

Solventado

Cita de: Xandrete en  5 Abril 2012, 01:39 AM
¿Qué quieres decir con borrar exactamente?
Borrar el contenido de la fila 'x' , lo que harias con un telefono vamos.. Seleccionar un nombre, y borrar esa fila, pero primero quiero que me salga lo de añadirlos.

Cita de: Xandrete en  5 Abril 2012, 01:39 AMPermíteme copiarte el case 3 del bloque switch:

Código (cpp) [Seleccionar]
                     afegir = afegir -1;
                     printf("Guardando cambios....");
                     fp=fopen("telefons.txt","a");
                     fprintf(fp,"%s %d\n" ,contacte,numero);          
                     printf("\nTots els canvis han sigut guardats");
                     fclose(fp);
                     for (int i=0;i<10;i++){ contacte[i]=0; numero[i]=0; }
                     break;


Lo que haces es:

- Decrementar el indicador de posición afegir.
- Guardar en el documento el nombre del contacto seguido de... un puntero Si pones "numero" a secas, ¡estás imprimiendo un puntero en el documento! De hecho, estás imprimiendo el puntero a la primera posición del array numero.
- Poner todas las posiciones de los arrays contacte y numero a 0. Mi pregunta es: ¿por qué guardas 10 números en un array si sólo vas a coger el último y el resto los borras?

Además, si borras todos los números, ¡deberías darle el valor 0 a afegir!

Ciertamente ya lo hago, porqué cada vez que vuelve al menu, tengo inicializado a 0 "afegir"

Código (cpp) [Seleccionar]
bool in_sortir=false; //boolea case 2
FILE *fp;
int espais=1;

//case 1, guarda numero i nom de contacte , variables
int afegir=0;
int numero[10];
char contacte[10];


No no, lo que he visto que, previamente deberia leer el documento a ver si contiene algun numero/nombre, y guardarlos en el array, y a partir de ahí, mirar si quedan huecos disponibles para añadir nuevos numeros. Si, está a 10 porqué en principio solo se deberían poder incluir 10 numeros, pero ahora mismo es algo "relativo" ya que busco que al menos me guarde 2 en el documento.

Así a "grosso modo", al programa yo le digo de añadir tantos numeros como quiera/pueda , y entonces, los guardo (o no). Si los decido guardar, deberian incluirse en el .txt , si quito el programa , se pierden los datos. De 1 en 1 ya he visto que si lo hace, pero a la que uso 2 o 3, siempre me guarda el ultimo.

Si, al "guardar" ya he visto que solo guardo uno, pero el problema es que si usaba el for (que verás más abajo), me petaba ..

Cita de: Xandrete en  5 Abril 2012, 01:39 AM

También es curioso el tratamiento que haces del array de caracteres contacte. A veces lo tratar como una cadena de texto (como en la sección de código anterior) y otras lo tratas como un vector de cadenas de texto, como en el siguiente fragmento:

Código (cpp) [Seleccionar]
                     printf("Introduce el numero : ");
                     scanf("%d", &numero[afegir]);
                     
                     printf("Introduce el nombre del contacto : ");
                     scanf("%s", &contacte[afegir]);
                     afegir++;
                     
                     break;


A no ser que los nombres tengan siempre longitud máxima de un carácter, deberías revisar esto.

¡Saludos!

si, prové de incluirlo mediante un bucle for, pero "petaba" a la hora de añadirlos, hice un

Código (cpp) [Seleccionar]
for (int i=0;i<=afegir;i++){ fscanf("%s %d", contacte[i], numero[i]}

Esta noche me lo reviso todo y te comento a ver como me queda.

durasno, por ahora estructuras no me piden, pero gracias por el aporte! En principio el programa debo hacerlo llano, sin funciones ni demás, con lo "básico de lo básico", es más que nada para "trabajar" los fscanf, fopen, fclose y el feof.

Xandrete

CitarCiertamente ya lo hago, porqué cada vez que vuelve al menu, tengo inicializado a 0 "afegir"

Cierto, no lo vi en su momento. Pero siendo así, ¿cuál es el objeto de decrementar la variable afegir? No la vuelves a utilizar en lo que queda del case 3 ni tampoco en el fragmento de código antes de entrar en el bloque switch.

Si me lo permites, pongo tu código con sangrías y entre etiquetas geshi:

Código (cpp) [Seleccionar]
#include <cstdio>
#include <iostream>

int main () {
bool sortir=false; // bolea, controla sortida 5


while(!sortir){ //bucle , sortida seleccio 1 - 5
int seleccio;

bool ok_seleccio=false; //boolea per controlar letras

//while(!ok_seleccio) { //controla que sean numeros

printf("\n********************\n");
printf("Menu ");
printf("\n********************\n");
printf("1.Introducir nuevo telefono \n2.Buscar por nombre  \n3.Guardar en disco \n4.Cargar listado  \n5.Salir\n\nSeleccion: ");
scanf("%d",&seleccio);

bool in_sortir=false; //boolea case 2
FILE *fp;
int espais=1;

//case 1, guarda numero i nom de contacte , variables
int afegir=0;
int numero[10];
char contacte[10];

switch(seleccio) {
                         
case 1:       
printf("Introduce el numero : ");
scanf("%d", &numero[afegir]);
                     
printf("Introduce el nombre del contacto : ");
scanf("%s", &contacte[afegir]);
afegir++;
                     
break;
case 2:
while(!in_sortir){
char nom[15];
printf("Introduce el nombre : ");
scanf("%s",&nom);
//... falta desarrollar ...

                         
                           
}
                     
break;
case 3:
afegir = afegir -1;
printf("Guardando cambios....");
fp=fopen("telefons.txt","a");
fprintf(fp,"%s %d\n" ,contacte,numero);         
printf("\nTots els canvis han sigut guardats");
fclose(fp);
for (int i=0;i<10;i++) { contacte[i]=0; numero[i]=0; }
break;
case 4:
                     
printf("Carregant llisti telefonic...\n");
fp = fopen("telefons.txt","r");
                     
char content[20];
while(!feof(fp)){
fscanf (fp, "%s", &content);
printf("\n%s ", content);
espais++;
if(espais==2){ printf("\n"); espais=0;}
}
fclose(fp);
                     
break;
case 5:
printf("Saliendo del programa...");
sortir=true;
break;
default:
if(seleccio<0 || seleccio>6){
printf("error en la seleccion, las opciones son del 1 al 5");
}
break;
                 
}
}
system("PAUSE");
   
return 0;   
}


CitarCiertamente ya lo hago, porqué cada vez que vuelve al menu, tengo inicializado a 0 "afegir"

En cualquier caso, ten en cuenta lo de que si pones numero a secas como parámetro del fprintf en el case 3, estás imprimiendo una posición de memoria. Eso sí que no creo que sea el comportamiento que buscas. En todo caso me imagino que querrás imprimir una o varias posiciones del array numero (para lo cual has de usar los corchetes []).

Por otro lado, claro que te peta cuando haces

Código (cpp) [Seleccionar]
for (int i=0;i<=afegir;i++){ fscanf("%s %d", contacte[i], numero[i]}

Para hacer algo en esa tesitura, tienes que declarar contacte como un array de arrays de caracteres. Exempli gratia, supongamos que quieres guardar 10 nombres de, como mucho, 50 caracteres cada uno. Entonces deberías declarar contacte como char contacte[10][50]. Entonces sí que podrías usar un bucle como el anterior.

Saludos