簡體   English   中英

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

[英]How to use arbitrary number of scanf() format specifiers?

我想在scanf()函數中使用無限類型說明符( %d )。

例如-

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

因此,不確定多少個數字。 用戶將輸入。 我不想讓我的程序問用戶“字符數” ..但是我想允許任何字符數。 但是不可能在scanf()輸入無限%d

那么,誰能告訴我用C語言程序查找用戶給出的平均數字的方法(如果您不知道用戶將給出多少個數字,並且您不希望該程序詢問“多少個數字”)?

這很棘手。 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);

如果您真的對無限數量的輸入感興趣,只需嘗試一下

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

在您強行關閉程序之前,將一直需要輸入!
但是這樣做有什么意義嗎?

如果用戶輸入的數字始終用空格分隔,則最后一個輸入(換行符)。 然后您可以使用以下代碼

#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]

myprogram5被保存為argv[]數組中的字符串。 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)

初讀時,解決此類問題的方法是循環播放,直到用戶輸入“完成”字符為止。 例如,這可以是字母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
}

我相信您可以在這里找到答案...

您應該以某種方式知道輸入在哪里結束。 有很多方法,每種方法可能都有不同的解決方案。 最常見的兩個是:

輸入在行尾完成

解決方案是先讀取一行 ,然后解析該行以獲取您的數字,直到該行結束。

這樣做的好處是,程序可以隨后向程序的其他部分請求其他輸入。 缺點是用戶必須在同一行中輸入所有數字。

輸入在文件末尾完成

簡單地循環,讀取一個數字直到文件結尾:

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

注意:用戶可以使用Ctrl + D在Linux控制台中輸入文件結尾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM