【问题标题】:Fill in an array from a single formatted keyboard line in C从 C 中的单个格式化键盘行填充数组
【发布时间】:2013-09-11 21:11:43
【问题描述】:

如何从一个任意长度的格式化(例如空格分隔)键盘行填充双精度或整数数组?

例如:

Enter the elements of the array:
2 32 12.2 4 5 ...

应该会导致

=> array[0] = 2
=> array[1] = 32 etc.

我知道我可以按如下方式使用 scanf,但这并不能解决我的问题,因为每个元素都应该一个一个地输入。

  /* Input data from keyboard into array */

  for (count = 1; count < 13; count++)
  {
      printf("Enter element : %d: ", count);
      scanf("%f", &array[count]);
  }

谢谢。

【问题讨论】:

  • 使用fgets从键盘读入整个字符串,然后扫描字符串-使用strtok查找空格,最后用sscanf解释“令牌”。
  • 切勿使用gets()!使用fgets() 阅读它,也许。 gets() 函数本质上是不可修复的不安全函数,已被弃用,从当前版本的 C 标准中排除,并被 POSIX 标记为已过时。
  • 您可以输入一串以逗号分隔的数字,例如“12.3,4.5,56.678,12.1,0.123”或任意长度。然后按回车键,将其作为字符串扫描。使用 strtok 将其拆分,然后使用 strtof() 将字符串转换为浮点数,并将它们分配给浮点数组。
  • @Floris:你不能认真推荐gets
  • 好吧好吧对不起错字了。我修好了它。我的意思是“以字符串的形式获取行并解析它”。

标签: c arrays fill keyboard-input formatted-input


【解决方案1】:

我知道我可以按如下方式使用 scanf,但这并不能解决我的问题,因为每个元素都应该一个一个地输入。

没有。如果您不使用换行符,那将完全正常。


一般来说,避免使用scanf() 是个好主意,不过——这不是最直观的函数(可以这么说)。使用fgets() 读取该行然后使用strtof() 解析它怎么样?

char buf[LINE_MAX];
fgets(buf, sizeof buf, stdin);

char *s = buf, *endp;
int i = 0;
for (i = 0; i < 13; i++) {
    array[i] = strtof(s, &endp);
    s = endp;
}

【讨论】:

  • 真的吗?我不认为您可以输入1 2 3 4 5 后跟CRLF 的字符串,并期望上面的代码为您提供一个包含1 到5 值的数组?我是否误解了您的答案或问题?
  • @Floris 我认为你对两者都有误解。
  • @H2CO3 - 您在答案中传达的内容的偏差很好,但在语法上并不正确。 Floris 的问题比你认为的更有价值。
  • @ryyker 对不起,我不明白你的问题是什么。 OP 认为每次想要scanf() 启动新的转换时都必须按 Enter。我指出事实并非如此。我什至提供了一个替代解决方案(类似于 Floris 的建议,只是不太复杂)。我也没有说弗洛里斯的评论是错误的。老实说,我不知道你在皱眉……
  • @verbose - 关于循环条件,我不确定它是否会更有效,但我很确定考虑到 OP 问题,不需要包含 *s != '\n'是问怎么做,不用每次都输入。他想输入一个任意长、格式化(例如空格分隔)的键盘行
【解决方案2】:

您不能有一个同时包含 intdouble 值的数组。您可以拥有int 的数组或double 的数组。如果您的输入中可能有任何doubles,您应该只声​​明一个double 数组。

您还必须设置数组的最大大小,并在填充该数量的元素时停止读取。在 C 中,您不能拥有动态大小的数组。如果你真的需要根据值的数量动态改变数据结构,你最好使用链表。

scanf() 不是一个很好的工具,因为它不会区分输入末尾的换行符和分隔数字的空格。使用fgets() 读取整行,然后使用sscanf() 将其拆分为数组元素。

数组的使用方法如下:

double ary[MAX_ARRAY_SIZE];    // MAX_ARRAY_SIZE being some defined value
char buffer [512];
char* ptr = buffer;
int i = 0;

printf ("Enter your values separated by spaces: ");
fgets (buffer, sizeof (buffer), stdin);

while (i < MAX_ARRAY_SIZE && ptr) {
    sscanf (ptr, "%lf", &ary[i]);
    ptr++;
    i++;
    ptr = strchr(ptr, '\040');
}

【讨论】:

  • 这是代码的一个工作示例:ideone.com/SvyaF7。请注意,假设只有一个空格分隔输入行上的每个值。如果有多个空格,则此代码将不起作用。 @H2CO3 的答案更可靠。
  • 错误提示“R6002 - 未加载浮点支持”。我错过了什么?
  • 我无法检查@H2CO3 的答案,是不是在 VS 2010 中没有定义 strtof?
  • 关于@H2CO3 的回答,你可能只需要#include &lt;stdlib.h&gt;。关于 R6002 错误:runtimerrorfix.blogspot.com/2013/05/….
  • 我已经包含了 stdlib.h 但不知何故它说 strtof 是未定义的。 strtod 没问题。
【解决方案3】:

您可以在变量初始化等方面做一些工作。但这会满足您的要求。

#include <ansi_c.h>

int main(void)
{
    char hold[20][10];
    double arr[20];//change size as necessary
    char *buf;
    char *toss;
    int i=-1, j=0;
    buf = malloc(260);
    toss = malloc(260);

    fgets(buf, 260, stdin);
    buf = strtok(buf, " ");
    while(buf)
    {
        strcpy(hold[++i], buf);
        arr[i] = strtod(hold[i], &toss);
        buf = strtok(NULL, " ");
    }

    for(j=0;j<i;j++)
    {
        printf("arr[%d]=%f\n", j, arr[j]);  
    }

    getchar();

    return 0;
}

【讨论】:

  • 谢谢,这段代码运行良好。只需在最后一个 for 循环中 make (j
猜你喜欢
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 1970-01-01
  • 2010-11-04
  • 2022-01-13
  • 1970-01-01
相关资源
最近更新 更多