将具有未知元素数的字符串扫描到C中的int数组

时间:2014-06-23 10:53:11

标签: c arrays string strtok scanf

我在C中的一个程序中工作,我有一串这样的字符:

5 13 12 7 3 0

我想扫描它并将每个整数放在一个int数组中。我怎么做? 这是一种使用sscanf的方法吗?

我尝试了以下代码但没有成功:

 fgets(datatemp, N*3, stdin);

 k = 0; garb = 'c';
    while(garb != '\0'){
      garb = strtok(datatemp, " ");
      array[k] = garb;
      k++;
    }

注意:我必须在一个函数中使用它,这个函数对于许多数据都是这样的,其中数据是' datatemp' string将具有未知数量的整数(并且只有整数)。

感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

// Adapted from strtok(3) example.

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

int
main(int argc, char *argv[])
{
  char *str1, *str2, *token, *subtoken;
  char *saveptr1,*saveptr2;
  int j;
  char datatemp[ 120 ];
  char delim = ' ';

  fgets(datatemp, 119, stdin);

  /*
   * strtok has to be called with a pointer to the input
   * the first time then with a pointer to the string
   * subsequently
   */

  for(j=1, str1 = datatemp;; j++, str1 = NULL)
  {
    token = strtok_r(str1, &delim, &saveptr1);

    if(token==NULL)
      break;

    for (str2 = token; ; str2 = NULL)
    {
      subtoken = strtok_r(str2, &delim, &saveptr2);
      if (subtoken == NULL)
        break;
      printf(" --> %s\n", subtoken);
    }
  }

  exit(0);

}

答案 1 :(得分:0)

我建议在循环中使用strtol,速度更快(没有中间缓冲区的直接转换)并且可以检查错误

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

int main(void)
{
    char s[128], *p, *q;
    int i, n, *v;

    /* get user input */
    fgets(s, sizeof s, stdin);
    /* count integers */
    for (p = s, n = 0; ; p = q, n++) {
        strtol(p, &q, 10);
        if (p == q) break;
    }
    v = malloc(sizeof(int) * n);
    /* populate array */
    for (p = s, i = 0; i < n; i++) {
        v[i] = strtol(p, &p, 10);
    }
    /* print array */
    for (i = 0; i < n; i++) {
        printf("%d\n", v[i]);
    }
    free(v);
    return 0;
}

答案 2 :(得分:0)

您可以使用标头strtol中声明的标准函数<stdlib.h>。例如

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


int main( void ) 
{
    char s[] = "5 13 12 7 3 0";
    size_t l = strlen( s );

    size_t n = 0;

    char *end_ptr = s;
    char **next_ptr = &end_ptr;

    errno = 0;

    while ( end_ptr != s + l )
    {
        strtol( *next_ptr, next_ptr, 10 );
        if ( errno != 0 ) break;
        ++n;
    }

    int a[n];
    memset( a, 0, n * sizeof( int ) );

    end_ptr = s;
    size_t i = 0;
    while ( end_ptr != s + l )
    {
        int value = ( int )strtol( *next_ptr, next_ptr, 10 );
        if ( errno != 0 ) break;
        a[i++] = value;
    }

    for ( i = 0; i < n; i++ ) printf( "%d ", a[i] );
    puts( "" );

    return 0;
}

输出

5 13 12 7 3 0

答案 3 :(得分:0)

要按照OP的要求使用fgets()/sscanf(),请参阅下文。

使用fgets()/strtol()可提供比sscanf()更好的错误处理。建议strtol()

为了获得最佳答案,OP需要提供数据如何存储(VLA,malloc,一次1个),错误处理问题等信息。

很难说为什么OP代码不能正常工作,因为缺少array[]的defalcation,但它可能对于测试数据来说太小了,而且根据各种数据输入的需要没有调整大小。

void foo() {
  char buf[100];
  if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();

  int i = 0;
  int n = 0;
  int number;
  // Count the numbers
  while (sscanf(&buf[i], "%d %n", &number, &i) == 1) {
    n++;
  }

  int num[n];
  i = 0;
  int j;
  // scan again, this time save the numbers
  while (sscanf(&buf[i], "%d %n", &num[i], &j) == 1) {
    i = j;
  }

  // use the numbers
  bar(num, n);
}

以上代码可能会使用j并使用while (sscanf(&buf[i], "%d %n", &num[i], &i) == 1);,但我需要仔细检查一些代码点问题。

strtol()优于sscanf()。要使用,建议一个辅助函数:

// return non-zero on failure 
static int user_strtoi(char **s, int *result) {
  char *endptr;
  errno = 0;
  long num = strtol(*s, &endptr, 10);
  if (endptr == *s) return 1; //  fail as nothing was parsed
  if (errno != 0) return 2; //  fail due to overflow
  if (num < INT_MIN || num > INT_MAX)  return 2; //  fail due to overflow
  *result = (int) num;
  *s = endptr;
  return 0;
}