如何在C语言中扫描多个用空格隔开的输入?

问题描述 投票:0回答:1

我是一个新的程序员,但我不能解决一个问题,所以我必须扫描f并检查它是否是一个整数(int n),然后读取n个浮点数(与检查它们是否是浮点数)。所以我必须扫描并检查它是否是一个整数(int n),然后读取n个floats(检查它们是否是floats)。问题是机器测试会在输入中添加多个用空格隔开的浮点数,我不知道如何获得这些数字。

我写了这样的东西。

  int n;
  if(!scanf("%d", &n)){
    printf("Invalid input");
    return 1;
  }
  float *tab = malloc(n*sizeof(float));
  printf("Enter variables: ");
  for(int i=0; i<n; i++){
    if(scanf("%f", (tab+i))!=1){
      printf("Incorrect input data");
      return 2;
    }
  }

我不知道这是否是好的,以及如果你在输入中输入更少或更多的数字该怎么办。 伙计们,请解释一下这里有什么问题,以及如何解决它。

谢谢您的时间。

c pointers scanf
1个回答
1
投票

如何在C语言中扫描多个用空格分隔的输入?

遇到的问题是,如何在C语言中扫描多个用空格隔开的输入?"%d""%f" 将很乐意处理由空格、制表符、行末等分隔的数字文本,但不会处理 辨别 在空格和行尾之间。 如果一行的输入不足,代码将读取下一行的输入。 如果输入过多,则整个行不被读取--行的其余部分将用于下一行的输入功能。

如果OP关注的是 的输入,最好读一个 的输入,然后进行解析。

我不知道这样做好不好,如果你在输入中输入的数字少了或者多了,该怎么办。

让自己负责:如果你指挥一个编码团队,你会想要什么?消耗并忽略非数字输入,消耗输入并报错,简单结束代码等。

除了 首次扫描,代码看起来很合理的样子。

对我来说,如果想让代码更健壮,我会丢掉 scanf() 并使用 fgets() 的帮助函数中进行解析。 然后 sscanf()strto*() 进行解析,如果没有达到预期,则进行投诉。


示例

当然,这个辅助功能对于如此简单的任务来说是矫枉过正的,然而它是一个很好的工具。帮手 函数--我可以在任何时候反复使用这个函数来读取一组的 float 从一行。 我可以根据需要进行改进(例如:更多的错误处理,处理过长的行,...)。

// Read 1 line of input.
// return EOF on end-of-file or stream error,
// else return number of float read, even if more than N.    
int get_floats(const char *prompt, float *dest, int N) {
  if (prompt) {
    fputs(prompt, stdout);
    fflush(stdout);
  }
  char buf[BUFSIZ];
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    return EOF;
  }

  char *endptr = buf;
  int floats_read = 0;

  // parse the line into floats     
  while (*endptr) {
    const char *s = endptr;
    float f = strtof(s, &endptr);
    if (s == endptr) {
      break;  // no conversion
    }
    if (floats_read < N) {
      dest[floats_read] = f;
    }
    floats_read++;
  }

  // Consume trailing white-space
  while ((unsigned char) *endptr) {
    endptr++;
  }
  if (*endptr) {
    return -1;  // Non-numeric junk at the end
  }

  return floats_read;
}

使用方法:

int n;
if(get_floats("Enter variables: ", tab, n) != n) {
  printf("Invalid input");
  return 1;
}

0
投票

答案其实很简单: 在你的scanf格式指定器前面加一个空格. 这告诉 scanf 在转换之前吃掉所有的空白。

就像这样。

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

int main() {
  int n;

  if (1 != scanf(" %d", &n)) {
    exit(1);
  }
  float *tab = calloc(n, sizeof *tab);
  if (!tab) {
    exit(3);
  }

  for (int i = 0; i < n; ++i) {
    if (1 != scanf(" %f", &tab[i])) {
      exit(2);
    }
  }

  const char *sep = "";
  for (int i = 0; i < n; i++) {
    printf("%s%f", sep, tab[i]);
    sep = ", ";
  }
  printf("\n");

  free(tab);
  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.