1

I have a problem with my C code, hope you can help me. The program is about making a basic book "database". When I run the following code (in Xcode), I don't know why the following sentence gets skipped:

gets(nombre[i]);

On the terminal it directly prints the following if I take option 1 from the menu:

Bienvenido al catalogo de libros.

Catalogo de tarjetas: 1. Introducir 2. Buscar por autor 3. Buscar por titulo 4. Salir

Elija opcion:1 warning: this program uses gets(), which is unsafe.

Introduzca el nombre del libro:Introduzca el autor del libro:

Ok, so i've tested my scanf("%d", &opcion); using a printf("%d", opcion); right after to proove that scanf reads correctly my input. Surprisingly, it reads the option I introduce correctly. Moreover, i've tried running the program with no "\n" in any part to see if gets(nombre[i]) works but still it gets jumped...

Any ideas?

This is the full code (not long):

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

#define MAX 100

char nombre[MAX][20];
char autor[MAX][20];
char edit[MAX][20];
char buscar[20];
char buscar_t[20];
char buscar_a[20];


int opcion,i,j,k,l;

void menu(void);
void intro(void);
void buscar_autor(void);
void buscar_tit(void);
void salir(void);

void main(void)
{
    printf("Bienvenido al catalogo de libros. \n");
    menu();
}




void menu(void)
{
    printf("\n Catalogo de tarjetas:");
    printf("\n 1. Introducir");
    printf("\n 2. Buscar por autor");
    printf("\n 3. Buscar por titulo");
    printf("\n 4. Salir");

    printf("\n Elija opcion:");
    scanf("%d", &opcion);

    switch (opcion) {
        case 1:
            intro();
            break;
        case 2:
            buscar_autor();
            break;
        case 3:
            buscar_tit();
            break;
        case 4:
            salir();
            break;

    }


}

void intro(void)
{
        for (i=0; i<MAX; i++) 
        {
            printf("Introduzca el nombre del libro:");
            gets(nombre[i]);

            if (!strcmp(nombre[i],"salir")) 
            {
                break;
            }

            printf("Introduzca el autor del libro:");
            gets(autor[i]);
            printf("Introduzca la editorial del libro:");
            gets(edit[i]);
        }

    menu();

}

void buscar_tit(void)
{
    printf("Introduzca el titulo del libro que quiera buscar:");
    gets(buscar_t);

    for (j=0; j<MAX+1; j++) 
    {
        if (!strcmp(nombre[j],buscar_t)) 
        {
            printf("El libro se ha encontrado, el titulo es %s. ", nombre[j]);
            break;
        }
        if (j=MAX) 
        {
            printf("El libro no se ha encontrado.");
            break;
        }

    }

}

void buscar_autor(void)
{
    printf("Introduzca el autor del libro que quiera buscar:");
    gets(buscar_a);

    for (k=0; k<MAX+1; k++) 
    {
        if (!strcmp(autor[k],buscar_a)) 
        {
            printf("El libro se ha encontrado, el titulo es %s. ", nombre[k]);
            break;
        }
        if (k=MAX) 
        {
            printf("El autor no se ha encontrado.");
            break;
        }
    }
}

void salir(void)
{
    printf("Muchisimas gracias por usar el catalogo de libros. \n");
}

Hope you can help me figure out the error.

Thanks guys.

  • 3
    Hello and welcome to stackoverflow.com. Please take some time to read [the help pages](http://stackoverflow.com/help), especially the sections named ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also please read [the Stack Overflow question checklist](http://meta.stackexchange.com/questions/156810/stack-overflow-question-checklist). You might also want to learn what a [SSCCE](http://sscce.org/) is. – Some programmer dude Aug 28 '13 at 11:47
  • 1
    The points about the checklist and SSCCE are important, as you should only try to post a *minimal* code example describing your problem. Not many people are willing to read many pages of code. Also, not many people here read whatever language it is you error message is in (Spanish? Portuguese?), but everyone knows English. You might want to change the locale settings on your system before compiling to get English error messages. – Some programmer dude Aug 28 '13 at 11:48
  • In this case though, have you simply tried replacing `gets` with [`fgets`](http://en.cppreference.com/w/c/io/fgets)? – Some programmer dude Aug 28 '13 at 11:49

1 Answers1

1

Please Avoid using gets. Use fgets specifying stdin as stream.

 char *fgets(char *s, int size, FILE *stream);

In your Code Modify this Function:

void intro(void)
{
        getchar(); //added this to avoid escaping at early stage of loop
        for (i=0; i<MAX; i++)
        {
            printf("Introduzca el nombre del libro %d : ",i+1); //modified this statement to know which iteration is going on by printing the loop counter value
            fgets(nombre[i],sizeof(nombre[i]),stdin); //  replaced  gets(nombre[i]);

            if (!strcmp(nombre[i],"salir"))
            {
                break;
            }

            printf("Introduzca el autor del libro: %d : ",i+1);
            gets(autor[i]);  //here also use fgets
            printf("Introduzca la editorial del libro %d : ",i+1);
            gets(edit[i]);   //here also use fgets 
        }

    menu();

}

small suggestion:

to make debugging easy, change #define MAX 100 to #define MAX 5

see this Safe Alternative to gets

in your case if the issue repeats with fgets just add getchar();
before fgets and also see this also How to clear input buffer after fgets overflow?

from the man pages of gets

BUGS Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will conâ tinue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Community
  • 1
  • 1
Gangadhar
  • 10,248
  • 3
  • 31
  • 50
  • 1
    Im sorry, but i'm kind of a begginer when talking about C. I've tried to change gets() for fgets() but I see that fgets() needs more arguments than gets(). Anyway, I've always used gets() therefore the program should work and the error has to be before the gets(nombre[i]); sentence. Thanks! – Jorge Sebastián Aug 28 '13 at 17:16