如何使用任意数量的scanf()格式说明符?

时间:2013-10-08 13:11:38

标签: c loops scanf

我想在%d函数中使用无限类型说明符(scanf())。

例如 -

printf("Enter numbers: \t");
scanf("--%d SPECIFIERS--");

所以它不确定有多少个。用户将进入。我不希望我的程序向用户询问'字符数'..但我想允许任何字符数。但是无法在%d中输入无限scanf()

所以任何人都可以告诉用户查找数字平均值的C程序是什么(如果您不知道用户会给出多少数量,并且您不希望程序询问'有多少数字。 “)?

5 个答案:

答案 0 :(得分:1)

这很棘手。 2种方法

1 - fgets()读取1行,然后解析

char buffer[1000];
int count = 0;
double sum = 0;
int num;
fgets(buffer, sizeof buffer, stdin);
const char *p = buffer;
int n;
while (sscanf(p, "%d%n", &num, &n) == 1) {
  p += n;
  ; // do something with `num`
  sum += num;
  count++;
}     
printf("Average %f\n", sum/count);

2 - 让我们说你的无限输入以行尾结束。现在问题是%d将消耗所有前导空格,包括\n。因此,我们需要预先使用和测试所有空格

int count = 0;
double sum = 0;
int num;
for (;;) {
  int ws = 0;
  while (isspace(ws = fgetc(stdin)) && (ws != '\n'));
  if (ws == '\n') break;
  ungetc(ws, stdin);
  if (scanf("%d", &num) != 1) break;
  ; // do something with num
  sum += num;
  count++;
}
printf("Average %f\n", sum/count);

答案 1 :(得分:0)

如果你真的对无限数量的输入感兴趣,那就试试吧

while(1)
{
    printf("Enter numbers: \t");
    scanf("%d", number);
}  

在您强行关闭程序之前,它会接受输入!
但它是否有任何意义这样做?

答案 2 :(得分:0)

如果用户输入始终是由空格分隔的数字,那么最后是输入(换行符)。然后您可以使用以下代码

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

int main(int argc, char *argv[])
{
    int input;
    char c;
    while (scanf(" %d%c", &input, &c) == 2 ) {
        printf("number is %d\n", input);
        if ( c == '\n') break;
    }
}

如果使用想要将输入的数量作为参数传达

int main(int argc, char *argv[])
{
    int number_of_input = atoi(argv[1]);
    int input, i;
    for (i=0; i<number_of_input; i++) {
        scanf(" %d", &input);
    }
}

当你给你打电话的时候。你用这种方式称呼它:

$ myprogram 5

和5这里是您可以输入的整数的数量

  • myprogram将保存在argv[0]
  • 5将保存在argv[1]

myprogram5argv[]数组中保存为sting。 atoi(argv[1])会将"5"字符串转换为5为整数


您也可以让用户以这种方式输入无限整数输入:

int main(int argc, char *argv[])
{
    int input, i;
    while (1) {
        scanf(" %d", &input);
    }
}

你可以给用户一种方法来阻止这种无限循环:

int main(int argc, char *argv[])
{
    int input;
    while (scanf(" %d", &input) != EOF) {
        //....
    }
}

这里你可以用

停止无限循环

EOF = CTRL + D (适用于Linux)

EOF = CTRL + Z (适用于Windows)

答案 3 :(得分:0)

在第一次阅读时,这样的问题的解决方案是循环,直到用户输入“完成”字符。例如,这可以是字母Q。通过将输入作为字符串读入,您可以处理数字和字母。下面的代码一次处理一个输入(后跟) - 可以退出(终止程序)或清除(重新启动计算,保持程序运行):

printf("Enter numbers to average. Type Q to quit, or C to clear calculation.\n");
char buf[256];
double sum=0, temp;
int ii = 0;
while(1)
{
    printf("Input: \t");
    fgets(buf, 255, stdin);
    if (tolower(buf[0])=='q') break;
    // allow user to "clear" input and start again:
    if (tolower(buf[0])=='c') {
      sum = 0;
      ii = 0;
      printf("Calculation cleared; ready for new input\n");
      continue;
    }
    ii++;
    sscanf(buf, "%lf", &temp);
    sum += temp;
    printf("At this point the average is %lf\n", sum / (double)ii);
}

printf("Done. The final average of the %d numbers is %lf\n", ii, sum / ii);

编辑在对此答案以及其他答案的评论中进行一些反复,这是一个解决您的问题的解决方案。代码已经过测试 - 它编译,运行,给出了预期的结果:

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

int main(void){
  double sum=0;
  int ii=0;
  char buf[256], *temp;
  char *token;

  printf("Enter the numbers to average on a single line, separated by space, then press <ENTER>\n");
  fgets(buf, 255, stdin);
  temp = buf;
  while((token=strtok(temp, " ")) != NULL) {
    temp = NULL; // after the first call to strtok, want to call it with first argument = NULL
    sum += atof(token);
    ii++;
    printf("Next token read is number %d: '%s'\n", ii, token); // so you see what is going on
                                                               // remove in final code!!
  }
  printf("AVERAGE: ***** %lf *****\n", sum / (double)ii);
  return 0;
}

再修改一次如果您想使用getline(您在评论中提到了这一点 - 它甚至比fgets更安全,因为它会增加缓冲区大小根据需要,你会改变一点点改变代码。我只是给出一些相关的部分 - 你可以弄清楚剩下的,我敢肯定:

double sum=0;
char *buf, *temp;      // declaring buf as a pointer, not an array
int nBytes = 256;      // need size in a variable so we can pass pointer to getline()
buf = malloc(nBytes);  // "suggested" size of buffer

printf("Enter numbers to average on a single line, separated with spaces\n")

if (getline(&buf, &nBytes, stdin) > 0) {
 temp = buf;
 // rest of code as before
}
else {
 // error reading from input: warn user
}

我相信你可以从这里弄明白......

答案 4 :(得分:0)

您应该某种方式知道输入结束的位置。它有很多种方法,每种方法都有不同的解决方案。最常见的两个是:

输入在行尾

结束

解决方案是read one line,然后解析该行以获取您的号码,直到该行结束。

这样做的好处是程序可以在事后为程序的其他部分请求其他输入。缺点是用户必须输入同一行中的所有数字。

输入在文件结尾处

结束

只需循环,读取一个数字直到文件结尾:

while (scanf("%d", &num) == 1)
    /* do something with num */

注意:用户可以使用 Ctrl + D

在Linux控制台中输入文件结尾