0

So I'm writing a program and there is this bit of code where I have to take the user input in stdin and make a choice of what to do. I've taken the bit of code corresponding to it and made another program (that is bellow) to check if the error keeps on. And it does. The error is when doing if(sscanf(buffer, "%*s %d %s %s%c", &key, succ_ip, succ_gate, &eol) == 4 && eol == '\n'), the second sscanf(), and i've figured that that sscanf() is != 4 witch was the value I was expecting since I'm asking for 4 variables.

The strange part is that it works just fine when strcmp(token, "new") == 0 but when strcmp(token, "sentry") == 0 it doesn't...

If anyone could help me I'dd be very thankful.

Here is the bit of my code where I'm having problems

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

#define Max 150

int main(){

  int key;
  char* succ_ip;
  succ_ip = (char*)malloc((Max+1)*sizeof(char));
  char* succ_gate;
  succ_gate = (char*)malloc((Max+1)*sizeof(char));
  char* s_succ_ip;
  s_succ_ip = (char*)malloc((Max+1)*sizeof(char));
  char* s_succ_gate;
  s_succ_gate = (char*)malloc((Max+1)*sizeof(char));

  char* buffer;
  buffer = (char*)malloc((5*Max+1)*sizeof(char));
  char* token;
  token = (char*)malloc((Max+1)*sizeof(char));
  char eol = 0;
  int block = 0;
  int exit_flag = 0;

  while(fgets(buffer, sizeof(buffer), stdin)){
      sscanf(buffer, "%s", token);
      /*NEW: creating the first server*/
      if(strcmp(token, "new") == 0 && block == 0){
        if(sscanf(buffer, "%*s %d%c", &key, &eol) == 2 && eol == '\n'){
          /*strcpy(succ_ip, argv[1]);
          strcpy(succ_gate, argv[2]);
          strcpy(s_succ_ip, argv[1]);
          strcpy(s_succ_gate, argv[2]);*/
          block = 1;
          printf("Chave : %d\n", key);
          printf("-> Ring created.\n");
        }
        else{
          printf("-> The command \\new is of type \"new i\". Where i is a key.\n");
          fflush(stdin);
          memset(buffer,0,sizeof(buffer));
          memset(token,0,sizeof(token));
        }
      }

      /*ENTRY: ... */
      else if(strcmp(token, "entry") == 0 && block == 0){

        /* do stuff */

        block = 1;
        printf("-> Server entered.\n");
      }

      /*SENTRY: adding a server specifying it's successor */
      else if(strcmp(token, "sentry") == 0 && block == 0){
        if(sscanf(buffer, "%*s %d %s %s%c", &key, succ_ip, succ_gate, &eol) == 4 && eol == '\n'){
          /*test for unique case when there are only 2 servers*/
          /*otherwise do the normal procedure*/
          /*tcp_client = init_tcp_cl(succ_ip, succ_gate);
          tcp_client = request_tcp_cl(tcp_client, "SUCCCONF\n");
          close_tcp_cl(tcp_client);*/
          printf("Chave : %d\n", key);
          printf("Next server ip: %s\n", succ_ip);
          printf("Next server ip: %s\n", succ_gate);
          block = 1;
          printf("-> Server sentered.\n");
        }
        else{
          printf("-> The command \\sentry is of type \"sentry i succ.ip succ.gate\". Where i is a key.\n");
          fflush(stdin);
          memset(buffer,0,sizeof(buffer));
          memset(token,0,sizeof(token));
        }
      }

      /*LEAVE: ... */
      else if(strcmp(buffer, "leave\n") == 0 && block == 1){
          /* do stuff */

          block = 0;
          printf("-> Left the ring.\n");
      }

      /* FALTA ADICIONAR O ESTADO DO SERVIDOR!!! */
      else if(strcmp(buffer, "show\n") == 0 && block == 1){
          /*printf("-> Key: %d\n-> IP: %s\n-> PORT: %s\n-> SuccIP: %s\n"
                    "-> SuccPORT: %s\n", key, argv[1], argv[2],
                      succ_ip, succ_gate);*/
      }

      /*FIND: ... */
      else if(strcmp(token, "find") == 0){
          /* do stuff */
      }
      /*EXIT: exits the application successfully*/
      else if(strcmp(buffer, "exit\n") == 0){
          printf("\nExiting the application...\n");
          exit_flag = 1;
      }
      /*Invalid command, ignores it*/
      else{
        printf("-> Invalid command.\n");
      }
  }
  return 1;
}
  • What exactly are the contents of `buffer` at that point in the code? (Try printing it.) What **does** `sscanf` return, if not 4? – Nate Eldredge Mar 18 '20 at 01:22
  • Thanks for posting complete code, but to understand the issue, we'd also need to see the input. – Nate Eldredge Mar 18 '20 at 01:23
  • 3
    By the way, `memset(buffer,0,sizeof(buffer));` is clearly wrong; `sizeof` does not detect the size of dynamically allocated regions. `sizeof(buffer)` returns the size of the variable `buffer`, which being a `char *` is likely 4 or 8 bytes. – Nate Eldredge Mar 18 '20 at 01:24
  • 4
    Similarly, `fgets(buffer, sizeof(buffer), stdin)` is also reading 4 or 8 bytes. I bet that is related to your problem. – Nate Eldredge Mar 18 '20 at 01:24
  • 2
    `fflush(stdin)` ?? The `fflush` function is for output streams – M.M Mar 18 '20 at 01:25
  • 1
    [Don't cast the result of malloc in C](https://stackoverflow.com/q/605845/995714). And `sizeof(char)` is always 1, no need to multiply with it – phuclv Mar 18 '20 at 01:36
  • thanks to all the fast comments. I've solved it thx to them :) – Pedro Antunes Mar 18 '20 at 01:38
  • 1
    the problme was what @NateEldredge said. Thank you. " sizeof(buffer) returns the size of the variable buffer, which being a char * is likely 4 or 8 bytes " – Pedro Antunes Mar 18 '20 at 01:39

1 Answers1

1

Like @NateEldredge said: "sizeof(buffer) returns the size of the variable buffer, which being a char * is likely 4 or 8 bytes."

Which was clearly causing the problem because when I wrote the input like: sentry 2 127.0.0.1 59001 the buffer wouldn't save all the info. so, of course, the sscanf() function couldn't get all variables. they weren't there.

ps: That fflush() shouldn't be there. I'm sorry...