【问题标题】:Split c console input into integers将 c 控制台输入拆分为整数
【发布时间】:2018-03-09 16:10:56
【问题描述】:

我有一个长度为 n 的整数的控制台输入空格分隔列表(n 通过控制台读取),需要将其拆分为整数并放置在大小为 n 的数组中。我已经尝试使用 fscan 和 fgets 进行此操作,以解决分段错误或控制台锁定问题,并且不让我进入列表。任何建议:

int main()
{
        int n;
        scanf("%d", &n);
        int buffer = n + n -1;
        char input[buffer];
        //char * input;
        //int buffer = n+n-1;
        //fgets(input, buffer, stdin);
        scanf("%*c", &input);
        printf("c is %c", input[0]);
        char * end;
        long int l;
        end = input;
        int base = 10;
        int ele = 0;
        long int vals[n];
        while(l = strtol(end, &end, base)){
                vals[ele] = l;
                ele += 1;
        }
        return 0;

【问题讨论】:

  • 试试int buffer = n + n + 1; char *input = malloc(buffer); fgets(input, buffer, stdin);
  • scanf("%d", &n); --> scanf("%d", &n); scanf("%*c");

标签: c segmentation-fault scanf fgets


【解决方案1】:

您的代码中发生了很多事情。下面是一个从标准输入读取可变大小数组的基本示例:

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

int main()
{
  int n;
  int *xs;

  /* read n */
  if (!scanf( "%d", &n ) || (n <= 0))
  {
    fprintf( stderr, "%s\n", "invalid n: n <= 0 or n is not an integer" );
    return 1;
  }

  /* allocate xs[n] */
  xs = (int*)malloc( n * sizeof(int) );
  if (!xs)
  {
    fprintf( stderr, "failure to allocate %d integers\n", n );
    return 1;
  }

  /* read xs[] */
  { 
    int i;
    for (i = 0; i < n; i++)
      if (!scanf( "%d", &(xs[i]) ))
      {
        fprintf( stderr, "%s\n", "invalid x: x is not an integer" );
        free( xs );
        return 1;
      }
  }

  /* ... */

  /* print xs[] in reverse order */
  {
    int i = n;
    while (i--)
      printf( "%d ", xs[i] );
    puts( "" );        // Here's your newline
    fflush( stdout );  // POSIX only mandates flush to terminal, and only by default
  }

  free( xs );
}

这应该可以帮助您走上正轨。

[编辑] 根据以下评论进行修改:

  • 在 C 中转换为 (int*) 不是必要的,但它:
    • 声明意图
    • 可以用 C++ 编译器编译而不会出错
  • 添加了非常简单的错误处理
    (“dog”现在将拒绝被接受为输入)
  • 添加了换行符。请注意,使用 fflush() 完全符合 POSIX。 POSIX 仅要求终端默认刷新换行符。没有换行符→需要刷新。管道到文件 → 请冲洗。

【讨论】:

  • malloc的返回不用强制转换,没必要。请参阅:Do I cast the result of malloc?。如果输入是1 2 3 4 cat 5 dog 6 ... 7,会发生什么?你怎么知道的?检查 scanfreturn 并处理任何 matchinginput 失败怎么样?删除 fflush( stdout ); 并在循环后添加 putchar ('\n') 有助于使您的程序符合 POSIX。
【解决方案2】:

你的编译器是否支持可变长度数组扩展:

#include <stdio.h>

int main (void) {

    int n, tmp, ndx = 0;
    if (scanf ("%d", &n) != 1 || n < 1) {
        fprintf (stderr, "error: invalid input - n.\n");
        return 1;
    }
    int a[n];

    while (ndx < n && scanf ("%d", &tmp) == 1) {
        a[ndx] = tmp;
        printf ("a[%3d] : %d\n", ndx, a[ndx]);
        ndx++;
    }

    return 0;
}

或者你选择动态分配你的数组:

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

int main (void) {

    int n, *a, tmp, ndx = 0;
    if (scanf ("%d", &n) != 1 || n < 1) {
        fprintf (stderr, "error: invalid input - n.\n");
        return 1;
    }

    if (!(a = calloc (n, sizeof *a))) { /* allocate/validate */
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

    while (ndx < n && scanf ("%d", &tmp) == 1) {
        a[ndx] = tmp;
        printf ("a[%3d] : %d\n", ndx, a[ndx]);
        ndx++;
    }

    free (a);   /* don't forget to free allocated memory */

    return 0;
}

始终,始终,验证所有用户输入(在将转换中的值分配给您的数组之前)scanf 有一个专门用于此目的的返回。您必须以某种方式处理 matchinginput 失败。

示例输入

$ cat dat/n_10_ints.txt
10
8572
-2213
6434
16330
3034
12346
4855
16985
11250

使用/输出示例

$ ./bin/readnints <dat/n_10_ints.txt
a[  0] : 8572
a[  1] : -2213
a[  2] : 6434
a[  3] : 16330
a[  4] : 3034
a[  5] : 12346
a[  6] : 4855
a[  7] : 16985
a[  8] : 11250
a[  9] : 1495

查看一下,如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 2019-07-26
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 2011-05-11
    • 2019-02-15
    相关资源
    最近更新 更多