这是一个很好的scanf替代方案吗?

carvr3hs  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(303)
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);

    }
}

我尝试用这个方法来代替scanf,它看起来像python中的input()函数,它把输入作为一个字符串,然后你把它转换成你想要的任何类型,这就是我用fgets()和strtol()所做的,我想问的是,这是否是scanf的一个很好的替代方案,或者有更好的解决方案可用?

v8wbuo2f

v8wbuo2f1#

fgets()在传递有效参数时是良好的。
fgets(n,25,stdin)在此代码中是错误的,因为指针n的值不确定。

  • 不要使用指针char *n;,而是使用char buffer[100];这样的示例大小的数组。我建议使用预期最大大小的2倍。
  • 使用sizeof确定数组大小,而不是幻数。
  • 检查fgets()返回值。
  • 避免在同一个程序中同时使用fgets()scanf(),我建议只在理解scanf()为什么有问题之前使用fgets()
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);
    }
}

其他代码问题:

  • 如果输入行过长,会发生什么情况?
  • 错误输入(如"123 zxfc\n"对应boxes[i].id)会发生什么情况?
  • fgets(boxes[i].name,50,stdin);是一个问题,因为boxes[i].name中很少需要尾随的'\n'。在读取后将'\n'归零,限制减少1,这是可以存储在boxes[i].name中的限制。

相关问题