1
void fill_boxes(box *boxes, int length)
{
    char *n;
    
    for (int i = 0; i < length; i++) {
        printf("Enter box %d id: ", i+1);
        //scanf("%d",&boxes[i].id);
        fgets(n,25,stdin);
        boxes[i].id = strtol(n,NULL,10);

        printf("Enter box %d name: ", i+1);
        //scanf(" %49[^\n]",boxes[i].name);
        fgets(boxes[i].name,50,stdin);

    }
}

I tried this method to replace scanf and it looks like the input() function in python where it takes the input as a string and then you convert it to whatever type you want, which is what I'm doing with fgets() then strtol(). I'm asking if this is a good alternative to scanf or are there better solutions available ?

1 Answers1

1

fgets() is good, when passed valid arguments.

fgets(n,25,stdin) is bad in this code as the value of pointer n is indeterminate.

  • Instead of using pointer char *n;, use an ample sized array like char buffer[100];. I recommend 2x the expected max size.

  • Use sizeof to determine array size, not a magic number.

  • Check fgets() return value.

  • Avoid using both fgets() and scanf() in the same program. I recommend using fgets() only until your understand why scanf() is problematic.

void fill_boxes(box *boxes, int length) {
    // char *n;
    char buffer[100];
    
    for (int i = 0; i < length; i++) {
        printf("Enter box %d id: ", i+1);
        // fgets(n,25,stdin);
        if (fgets(buffer, sizeof buffer ,stdin) == NULL) {
          printf("No valid input\n");
          break;
        }
        boxes[i].id = strtol(n,NULL,10);

        printf("Enter box %d name: ", i+1);
        // fgets(boxes[i].name,50,stdin);
        if (fgets(buffer, sizeof buffer ,stdin) == NULL) {
          printf("No valid input\n");
          break;
        }

        snprintf(boxes[i].name, sizeof boxes[i].name, "%[^\n]", buffer);
        // or
        buffer[strcspn(buffer, "\n")] = 0; // Lop off potential \n
        snprintf(boxes[i].name, sizeof boxes[i].name, "%s", buffer);
    }
}

Additional code concerns:

  • What should happen if the line of input is excessively long?

  • What should happen with errant input like "123 zxfc\n" for boxes[i].id?

  • fgets(boxes[i].name,50,stdin); is a problem as rarely is the trailing '\n' desired in boxes[i].name. Zeroing the '\n' after the read, limits reduces by 1, what could be stored in boxes[i].name.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256