【问题标题】:Pass an unknown number of integers with scanf使用 scanf 传递未知数量的整数
【发布时间】:2016-09-25 15:58:20
【问题描述】:

我需要创建一个未知大小的整数数组并将它们全部传递。我的代码如下所示:

int FillTable(int a[], int max){
  int i;
  int x = 0;
  int m = 0;
  for (i = 0; i < max; i++){
    printf("Fill the table with integers: ");
    scanf("%d", &m);

    if (m != "" && m != NULL){
      a[i] = m;
    }else if (m != "" && m == NULL){
      a[i] = 0;
    }else{
      break;
    }
  }
  printf("\n");
  return 0;
}

我知道您可以传递多个用空格分隔的整数,例如:

scanf("%d %d %d", &var1, &var2, &var3);

但我不知道如何传递一些我不知道会有多少的整数。我可以用一堆 %d 创建一个字符串,然后重复 max 次吗?我不知道,但现在,我只要求整数,直到数组已满,如果用户不输入,我需要能够让数组小于 max足够的价值。有人对我将如何扫描未知数量的整数有任何想法吗?

【问题讨论】:

  • 你没有说你的代码有什么问题。这看起来像 XY problem
  • @AT-2016 为什么这个问题是相关的?
  • @iharob,编辑它以更好地询问问题
  • 检查 m 不是查看是否已读取值的方法。 scanf() 返回一个值,指示它已读取多少个值。如果它返回零(表示它没有读取任何值)或EOF(表示错误情况),那么您可以停止读取。阅读文档!

标签: c arrays


【解决方案1】:

有人对我将如何扫描未知数量的整数有任何想法吗?

这需要动态内存分配!

扫描未知数量的整数的一种方法是,首先分配一个整数数组,其大小可以容纳max的整数个数。

如何知道用户是否结束输入?

  • 如果您只在数组条目中扫描用户的正整数,则提示他通过输入负数来结束输入
  • 或者如果您确定输入条目的范围,则在用户输入超出范围的输入时跳出循环

示例: (仅考虑用户输入的正数)

//creating a large enough array to store user inputs
int *array = malloc(sizeof(int) * max); 

//check if memory was allocated or not    
if(array == NULL)
{
    printf("memory allocation problem!");
    exit(1);
}

//integer to make note of size of array or you can use the sizeof() function instead
int size_of_array = 0;

for (i = 0; i < max; i++)
{
    printf("Fill the table with integers: ");

    if(scanf("%d", &m) != 1) //check for scanf return value
    {   
        printf("wrong input, try again");

        char consume; //to consume the character
        scanf("%c", &consume);

        i--;
        continue;
    }

    if (m > 0) //if positive number, accept
    {
        array[i] = m;
        size_of_array++;
    }

    else       //else break out of scanning
    {
        break;
    }
}

//do the program.....

//don't for get to free the memory at the end
free(array);

这是一个工作示例:https://ideone.com/BHN4sk

【讨论】:

  • 你也应该检查scanf()的返回值。
  • 嘿@RobinGoodfellow,如果任何答案对您有帮助,您可以考虑接受其中任何一个并将其标记为已接受:)
【解决方案2】:

您正在尝试做一些不必要的事情。预测数组的大小并重新分配适当的确切大小会在计算上更加昂贵(就 cpu 时间而言),因此节省您已经分配的内存的好处是不够的。 p>

中数组的大小存储在某个地方,不一定与数组本身有任何关系。所以你只需要知道有多少数组元素对程序来说是有趣的就行了。

你可以有类似的东西

struct Array {
    int *data;
    size_t size;
    size_t count;
};

其中size 是数组的总大小,count 是数组中元素的数量,data 是元素。我经常使用这种模式,它很有用,特别是如果与realloc() 结合使用,因为它可以避免不必要地重新分配内存的次数过多,而代价是使用的内存比实际需要的多一点。

但是今天的系统有更多的内存可以使用(除非你使用 Android Studio,它可以使用你的计算机所拥有的尽可能多的内存)。

【讨论】:

    【解决方案3】:

    首先,m != "" &amp;&amp; m != NULL 可能不会像您认为的那样做。你可能来自不同的语言。 (我认为)该语句所做的是将整数变量 m 中的值与字符串文字 "" 的地址进行比较,然后将其与 NULL(其计算结果为 0)进行比较。

    其次,scanf 默认读取到空格或换行符为止。

    scanf 失败时返回负数,因此您的代码应如下所示:

    for (i = 0; i < max; i++){
      printf("Fill the table with integers: ");
      if(scanf("%d", &m) > 0) {    
        a[i] = m;
      }
      else {
        break;
      }
    }
    

    我省略了 a[i] = 0 分支,因为我不明白你想要在那里。

    此外,您永远不会使用变量 x - 除非您遗漏了更多代码。

    【讨论】:

      【解决方案4】:

      你的问题对我来说不是很理解,但是我认为这会对你有所帮助

      int arraySize = 200; // Or whatever
      int *array_ = malloc(arraySize * sizeof(int));
      

      使用这个并将*array_作为参数传递,首先定义数组大小或获取数组大小作为用户输入,然后运行for循环直到数组大小

      【讨论】:

        【解决方案5】:

        您应该决定用户如何停止输入(并在提示中包含此信息)。一种快速而肮脏的方法是“输入任何不是数字的东西”。我选择了这种终止输入的方式,因为它很容易实现(因此又快又脏):

        printf("Fill the table with integers; terminate with 'x':\n");
        for (i = 0; i < max; i++)
        {
            int result = scanf("%d", &a[i]);
            if (result != 1)
                break;
        }
        

        注意:

        • 提示尽量用户友好
        • scanf 函数将数字直接放入数组中,不使用任何中间变量
        • scanf 函数返回读取了多少个数字,通常为 1;如果不是 1,则用户输入 x 或其他任何内容
        • 代码完成后,i 保存迭代次数,显示从用户那里读取了多少数字。

        您的输入函数应该返回数组的大小:

        return i; // instead of "return 0"
        

        您可能还想清理stdin 缓冲区 - 丢弃用户输入的任何内容以终止数组:

        while (getchar() != '\n')
        {
            // do nothing - keep consuming input until end-of-line
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多