c - 读取整数之间用逗号分隔

标签 c strtok

由于输入的格式,我认为使用 strtok 是最好的。 但我在尝试检测错误时遇到了一些问题:

程序将读取的一行示例:

 .data 123,456,89 
 .data     12,   34,   53   ,   64

这些都可以。

我的问题是当输入不正确时,例如:

 .data 200 4000 // no comma speration
 .data 1, ,3 // ,3 should be an error
 .data 4, // the extra , should be an error
 .data 12.2 // the .2 should be an error
 and so on

我的代码(SIZE适用于缓冲区大小= 30,valid_num遍历 token 以查看所有字符是否都是数字),想法是首先检查 token 的有效性并将它们添加到缓冲区,如果所有数字有效,请将数字添加到我的数据库:

 while((sptr = strtok(NULL, ", \t\n")) != NULL){ //this is after reading using strtok before.
    if(i < SIZE && valid_num(sptr)){ //buffer is not full and the token contains only numbers
        temp_num = atoi(sptr);
        if(temp_num >= MIN_VAL && temp_num <= MAX_VAL){ //number is within the required size
            buffer[i] = temp_num; /*fill buffer*/
            i++;
        }
        else{
            fprintf(stderr, "(%d) Error: %d is out of bounds. Valid numbers are between %d and %d\n", line_count, temp_num, MIN_VAL, MAX_VAL);
        }
    }
    else{
        fprintf(stderr, "(%d) Error: %s is not a valid number\n",line_count, sptr);
    }
    tok_count++;
}

if(i == tok_count){ //if all tokens were read correctly, add the data to database.
    DC += add_data(buffer, tok_count, DC, data_Table);
}
else{
    if(sptr != NULL){
    fprintf(stderr, "(%d) Error: %s is not a digit, .data can only be used for integers\n", line_count, sptr);
    }

}

即使输入的长度未知,我是否应该尝试使用 sscanf 执行相同的操作?

如何强制执行某种模式?数字 - 逗号 - 数字...

也许在循环内使用一些不同的strtok

最佳答案

解析该行的方法有很多

OP 的 temp_num = atoi(sptr); 不会检测溢出,因为 1) atoi() 的溢出未定义,2) 没有错误返回值。

<小时/>

我相信下面的内容能够应对所有敌意的输入。它不使用 strtok(),而是使用 strtol() 来查找非数字输入。

使用辅助函数可以使每个步骤更加清晰。

#include <ctype.h>
#include <errno.h>
#include <stdlib.h>

void consume_whitespace(char **input) {
  while (isspace((unsigned char ) **input))
    (*input)++;
}

int parse_int(char **input, int *dest) {
  char *endptr;
  errno = 0;
  long y = strtol(*input, &endptr, 10);
  if (*input == endptr) return -1; // no conversion
  if (errno) return -1;  // overflow
  #if LONG_MIN < INT_MIN || LONG_MAX > INT_MAX
    if (y < INT_MIN || y > INT_MAX) return -1;  // overflow
  #endif
  *input = endptr;
  *dest = (int) y;
  return 0;
}

int parse_data_line(char *input, const char *prefix, int *dest, int n) {
  size_t prefix_length = strlen(prefix);
  if (memcmp(input, prefix, prefix_length)) return -1;
  input += prefix_length;

  int i;
  for (i = 0; i < n; i++) {
    consume_whitespace(&input);
    if (*input == '\0') break;
    if (i > 0 && *input++ != ',') return -1;
    if (parse_int(&input, &dest[i])) return -1;
  }
  consume_whitespace(&input);
  if (*input) return -1;  // extra text
  return i;
}

使用示例

#define SIZE 30
int main() {
  int numbers[SIZE];
  char *input = foo();
  int count = parse_data_line(input, ".data", numbers, SIZE);
  if (count < 0) puts("Fail");
  else bar(numbers, count);
}

关于c - 读取整数之间用逗号分隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43071237/

相关文章:

c 字符串基础知识,为什么未分配?

c - getnameinfo() 是否可用于返回单个 IP 地址的多个主机名

c++ - gcc 和 clang 在使用无符号值左移时产生不同的输出

C 多个Strtok确定分隔符

c - 如何在 C 中解析带有换行符的字符串?

c++ - 使用 intel pin 工具的堆栈分配大小

java - 在 Ubuntu Linux 中查找 C/C++ 源代码的最佳工具是什么?

c - 在 C 中将字符串分成两半的问题

c - 将字符串拆分为标记

c - 不同编译器的 strtok() 行为不同