segmentation fault en mi programa

Iniciado por :Luigi, 29 Noviembre 2014, 14:53 PM

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

:Luigi

Buenas a todos. Me registre hace mucho tiempo (no recuerdo porque motivo) pero nunca he posteado nada. Ahora estoy estudiando programacion en C de forma autodidacta y es ahora cuando necesito esa ayuda que puede aportarme este foro (no puedo permitirme un profesor particular economicamente).Os agradecere toda ayuda recibida.

Bueno, tengo que hacer un ejercicio en el que se pregunta al usuario el nombre de un archivo de texto y el programa debe abrir dicho archivo y mostrar 25 lineas hasta que se pulse una tecla y mostrar otras 25, asi hasta la marca eof del archivo en si. El problema esta en que al compilarlo me da 0 errores pero al ejecutarlo me da "segmentation fault (core dumped)" dentro de la terminal donde lo ejecuto:


#include <stdio.h>
#include <string.h>

#define RUTA "/home/miusuario/"

main()
{
   FILE* archivo;
   char nombre[51];          //El nombre del archivo.
   char rutatemp[201];     //La ruta completa del archivo
        char linea[501];
   int i;      //Un contador para imprimir 25 lineas.

   printf("Escribe el nombre de archivo para abrirlo\n\n");
   gets(nombre);

   strcat(rutatemp, RUTA);
   strcat(rutatemp, nombre);

   archivo = fopen(rutatemp, "rt");

   while (! feof(archivo))
   {
      for (i = 0; i < 25; i++)
      {
         fgets(linea, 500, archivo);
         printf("%s", linea);
      }
      i = 1;
                getchar();
   }
   fclose(archivo);
}


La verdad no se si es que no se usar alguna funcion bien o que es. Me gustaria si es posible que no me corrigierais el codigo (me gusta intentarlo yo mismo para aprender) sino que me gustaria saber el porque de ese error en este codigo o que funcion es la que me falla y me ayudeis a entenderla. He leido tambien un post aqui mismo en el que se dice que hay funciones que no se deberian usar y yo utilizo aqui pero estoy obligado a ello. Gracias de antemano!!!

PD: Utilizo un curso de C escrito por Nacho Cabanes, si sabeis de alguno que sea mejor que ese os lo agradeceria muchisimo.

avesudra

#1
Hola, si pones cualquier cadena e imprimes rutatemp, te salen unos caracteres raros al principio:
Escribe el nombre de archivo para abrirlo

hola
 H♦/home/miusuario/hola
Process returned 255 (0xFF)   execution time : 8.799 s
Press any key to continue.
, quizás eso al pasarselo a fopen o a alguna función es lo que te está fallando. ¿cómo lo arreglo? pues inicializando todo el arreglo a 0 con memset (o con la función strcopy que te indica el compañero rir3760 en el siguiente post al mío).


Código (cpp) [Seleccionar]
void * memset ( void * ptr, int value, size_t num );
Fill block of memory
Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).


En concreto tienes que poner esto para inicializar esa zona de memoria en cero:
Código (cpp) [Seleccionar]
memset(rutatemp, 0, 51);
Otra forma de hacerlo sin usar memset es:
Código (cpp) [Seleccionar]
char rutatemp[201];     //La ruta completa del archivo
rutatemp[0] = '\0';




También deberías controlar la entrada con la funciones fgets + sscanf.

Además debes mirar si el archivo se ha abierto, si no te dará el segmentation fault. Con un simple if lo puedes comprobar:
Código (cpp) [Seleccionar]
archivo = fopen(rutatemp, "rt");
if(archivo)
   // Lo que quieras hacer con el archivo
else
   printf("Error al abrir el archivo");


Sé que no querías código pero la mejor manera es ejemplificando, la programación es aprender de los errores, si alguien te puede sacar de estos comederos de cabeza mejor.
Un saludo.
Regístrate en

rir3760

Como ya te menciono avesudra el error es utilizar la función strcat en la linea:
strcat(rutatemp, RUTA);
Esto porque si no se inicializa una variable su valor inicial es no definido o basura. La forma mas fácil de solucionarlo es utilizando en su lugar la función strcpy:
strcpy(rutatemp, RUTA);

También hay que cambiar la definición de la funcion main, indicar su valor de retorno y evitar el uso de la función gets, mas información en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

:Luigi

Hola muy buenas y gracias por vuestras respuestas. Lo primero es que la funcion gets aunque se que es peligrosa usarla (te lo dice el propio compilador) me veo obligado por el propio ejercicio.

Lo del strcat(rutatemp,RUTA);  lo cambie por un strcpy como bien me deciais para que se iniciase la variable bien. Puse tambien antes del while un printf("archivo abierto");getchar();   
basicamente para asegurarme de que el archivo se podia abrir, ademas cambie el "rt" del fopen por tansolo "r".

Puse un if que estaba en el exterior del while para evitar que si no se podia abrir el archivo se fastidiara el programa.
if(archivo != NULL);
Despues de todo lo anterior descubri que por algun motivo no se podia abrir el archivo, el error venia por parte de RUTA que no estaba correctamente colocada porque me faltaba una "/".

Al final del todo el codigo quedo asi, lo dejo por si alguien lo necesita por el mismo error o ejercicio:


/* lectura de ficheros por nombre
* read3.c */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define RUTA "/home/-miusuario-/"

int main()
{
FILE * archivo;
char nombre[51];
char rutatemp[201];
char linea[501];
int i;

printf("Escribe el nombre de archivo para abrirlo\n\n");
gets(nombre);

strcpy(rutatemp, RUTA);
strcat(rutatemp, nombre);

  printf("\n%s\n", rutatemp);getchar();

archivo = fopen(rutatemp, "r");
  if (archivo != NULL)
  {
    while (! feof(archivo))
    {
      system("clear");
      for (i = 0; i < 20; i++)
      {
        fgets(linea, 500, archivo);
        if (! feof(archivo))
        printf("%s", linea);
      }
      i = 1;getchar();
    }
    fclose(archivo);
  }
  else
  printf("El archivo no se ha podido abrir.");

  FIN:
  return 0;
}


Muchas gracias por haber contestado, me ha ayudado mucho.