0

Here's my code

if(passwordCorretta(ds_sock)){
   printf("CLIENT: password aggiungi corretta\n");

   do{
      printf("Cognome >> ");
      fgets(cognome,sizeof(cognome),stdin);
      //scanf("%s", cognome);
      printf("Nome >> ");
      fgets(nome,sizeof(nome),stdin);
      //scanf("%s", nome);
      printf("Telefono >> ");
      fgets(telefono,sizeof(telefono),stdin);
      //scanf("%s", telefono);

in output print first the two printf,skipping first fgets(), why is that?

here's my output

CLIENT: password aggiungi corretta
Cognome >> Nome >> **my input
Telefono >> **my input

any ideas why? thanks

Here's my entire function

void main(){
int ds_sock, length, res;
struct sockaddr_in client;
struct hostent *hp;
char oper[2];

int risPwd;
int op;

char cognome[30];
char nome[20];
char telefono[12];

char continua[3];
char ris[2];
int trovato;
int aggiunto;

ds_sock = socket(AF_INET, SOCK_STREAM, 0);

client.sin_family = AF_INET;
client.sin_port = 1999;

hp = gethostbyname("localhost");  //indirizzo del server
memcpy(&client.sin_addr, hp->h_addr, 4);

res = connect(ds_sock, &client, sizeof(client));
if(res==-1) {
    perror("Errore nella connessione");
}

signal(SIGPIPE, gest_broken_pipe);
signal(SIGINT, gest_interruzione);

do{
    op=scelta();
    sprintf(oper,"%d",op);
    if(write(ds_sock, oper, sizeof(oper))<0){
        if(errno!=EINTR) perror("Errore di scrittura");
    }

    switch(op){
            case 1:
                printf("INSERIMENTO NUOVO CONTATTO\n");

                if(passwordCorretta(ds_sock)){
                    printf("CLIENT: password aggiungi corretta\n");

                    do{
                        printf("Cognome >> ");
                        fgets(cognome,sizeof(cognome),stdin);
                        //scanf("%s", cognome);
                        printf("Nome >> ");
                        fgets(nome,sizeof(nome),stdin);
                        //scanf("%s", nome);
                        printf("Telefono >> ");
                        fgets(telefono,sizeof(telefono),stdin);
                        //scanf("%s", telefono);
                        if(write(ds_sock, cognome, sizeof(cognome))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }
                        if(write(ds_sock, nome, sizeof(nome))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }
                        if(write(ds_sock, telefono, sizeof(telefono))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }

                        if(read(ds_sock, ris, sizeof(ris))<0){
                            if(errno!=EINTR) perror("Errore di lettura");
                        }
                        trovato=atoi(ris);

                        switch(trovato){
                            case 0:
                                printf("Errore di lettura nel Server\n");
                                break;
                            case 1:
                                printf("Il contatto è già presente nell'elenco\n");
                                break;
                            case 2:
                                if(read(ds_sock, ris, sizeof(ris))<0){
                                    if(errno!=EINTR) perror("Errore di lettura");
                                }
                                aggiunto=atoi(ris);
                                if(aggiunto==0) printf("Errore di scrittura nel Server\n");
                                else printf("Il contatto è stato correttamente inserito nell'elenco\n");
                                break;
                        }

                        printf("Vuoi aggiungere un altro contatto? [SI/NO]\n");
                        scanf("%s", continua);
                        if(write(ds_sock, continua, sizeof(continua))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }
                    }while(strcmp(continua, "SI")==0);

                }
                break;

            case 2:
                printf("RICERCA DI UN NUMERO TELEFONICO\n");

                if(passwordCorretta(ds_sock)){
                    printf("CLIENT: password cerca corretta\n");

                    do{
                        printf("Cognome >> ");
                        scanf("%s", cognome);
                        printf("Nome >> ");
                        scanf("%s", nome);
                        if(write(ds_sock, cognome, sizeof(cognome))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }
                        if(write(ds_sock, nome, sizeof(nome))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }

                        if(read(ds_sock, ris, sizeof(ris))<0){
                            if(errno!=EINTR) perror("Errore di lettura");
                        }
                        trovato=atoi(ris);

                        switch(trovato){
                            case 0:
                                printf("Errore di lettura nel Server\n");
                                break;
                            case 1:
                                if(read(ds_sock, telefono, sizeof(telefono))<0){
                                    if(errno!=EINTR) perror("Errore di lettura");
                                }
                                if(strcmp(telefono, "errore")==0) printf("Errore di lettura nel Server\n");
                                else printf("Il telefono del contatto richiesto è: %s\n", telefono);
                                break;
                            case 2:
                                printf("Il contatto non è presente nell'elenco\n");
                                break;
                        }

                        printf("Vuoi cercare un altro numero di telefono? [SI/NO]\n");
                        scanf("%s", continua);
                        if(write(ds_sock, continua, sizeof(continua))<0){
                            if(errno!=EINTR) perror("Errore di scrittura");
                        }
                    }while(strcmp(continua, "SI")==0);

                }
                break;

            case 3:
                printf("USCITA\n");
                break;

            case 0:
                printf("Eseguito lo SHUTDOWN del Server\n");
                break;
    }

}while(op!=3 && op!=0);

close(ds_sock);

}

i use 3 buffer named cognome,nome,telefono. ideas?

Greg917
  • 13
  • 4
  • 2
    I think that you skipped the important part of the code. – Iharob Al Asimi Apr 30 '15 at 15:04
  • Show the definitions of `cognome`, `gnome`, and `telefono`. – R Sahu Apr 30 '15 at 15:17
  • i do that on purpose because there are many lines of code, but if is usefull i can post all code – Greg917 Apr 30 '15 at 15:17
  • 1
    It's probably consuming a line already present in the input buffer. My guess would be that you are using `scanf()` (or `getchar()`) before using `fgets()`. – user12205 Apr 30 '15 at 15:18
  • @Greg917 What's in `scelta()`? And specifically, does it read stdin? – user12205 Apr 30 '15 at 15:26
  • If you know that there is something left in input buffer, just add a `fgets` before `printf("Cognome >> ");` - no, joking - it could work but is ugly until you know **why** – Serge Ballesta Apr 30 '15 at 15:35
  • 'int scelta(){ int comando; menu(); puts("Inserisci l'operazione da effettuare: "); fgets(comando,sizeof(comando),stdin); //scanf("%d", &comando); while(comando<0 || comando>3){ puts("Operazione sconosciuta, riprovare: "); menu(); fgets(comando,sizeof(comando),stdin); //scanf("%d", &comando); } return comando; }' – Greg917 Apr 30 '15 at 15:38

2 Answers2

1

The problem is in your scelta() function. Both versions of it (with scanf() or fgets()) are wrong.

First I will explain why your fgets() version is wrong.

You declared comando as int, while fgets() expects a char *. This is undefined behavior, and you're lucky (or unlucky) it didn't crash.

As for your scanf() version: This is exactly what I predicted in the comments. scanf() only reads the integer input, and leaves the new line (ENTER key) in the input buffer. This means that your first fgets() call in main() is reading this left-over ENTER key.

One way of doing this correctly is as follows:

long int scelta() {
    char input[20];
    fgets(input, sizeof input, stdin); // this reads input
    while(strchr(input, '\n') == NULL) {
        // the input has not ended
        // it is probably not a long int anyway but you still need to consume it
        // choose your appropriate action, e.g.
        while(getchar() != '\n'); // read everything in input buffer up to (and including) the ENTER key
        puts("error");
        fgets(input, sizeof input, stdin); // read input again
    }
    char *endptr;
    long int comando = strtol(input, &endptr, 10);
    // then check range and check for errors with endptr
    return comando;
}

For a detailed description and example code (with error-checking) of strtol(), please refer to the Linux Programmer's Manual.

user12205
  • 2,684
  • 1
  • 20
  • 40
0

If it is supported by your system, the function fpurge cleans input streams and could be used in that case :

if(passwordCorretta(ds_sock)){
   fpurge(stdin);
   printf("CLIENT: password aggiungi corretta\n");

   do{

and do not try to use fflush because it only acts on output streams.

But anyway, you should try to understand where the unwanted input comes from. This is not far from a quick and dirty hack but at least is harmless is nothing was left in buffer.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252