C scanf() 扫描集从控制台读取逗号分隔值(字符串和整数)

C scanf() scansets to read comma separated value (string and integer) from console

我有以下任务:

Read comma separated data in below format:
string1, string2, integer_number
e.g:

  Hi, Hello, 123
  John, Doe, 45

我写了下面的代码来处理这种情况。 问题是我必须区分以下情况:

使这项任务变得更加困难的是要求使用任何由[]声明的或动态分配的额外数组。这必须仅使用这 3 个变量来完成。不允许使用其他缓冲区。

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

int main()
{
    char string1[20];
    char string2[20];
    int number;
    printf("Type data:\n");
    int ret_val = scanf("%[a-zA-Z], %[a-zA-Z], %d", string1, string2, &number);
    if (ret_val != 3) {
        printf("ret_val %d", ret_val);
        return 1;
    }
    printf("%s %s %d\n", string1, string2, number);
    return 0;
}

我通常依赖于 *scanf() 的技巧是使用 %n 来检测到此时输入已被读取;这在您期望某些文字时特别有用(它们不在 *scanf() 的结果中考虑)。

请注意,根据 man 3 sscanf%n 不在 *scanf() 的结果中考虑。

/**
  gcc -std=c99 -o prog_c prog_c.c \
      -pedantic -Wall -Wextra -Wconversion \
      -Wc++-compat -Wwrite-strings -Wold-style-definition -Wvla \
      -g -O0 -UNDEBUG -fsanitize=address,undefined
**/

#include <stdio.h>

void
parse_line(const char *line)
{
  printf("[%s] --> ", line);
  char string1[20]="";
  char string2[20]="";
  int number=-1;
  int n1=-1, n2=-1;
  int r=sscanf(line, "%[a-zA-Z],%n %[a-zA-Z],%n %d",
               string1, &n1, string2, &n2, &number);
  switch(r)
  {
    case 3:
    {
      printf("3 fields extracted: %s %s %d\n", string1, string2, number);
      break;
    }
    case 2:
    {
      if(n2!=-1) // this coma has been read
      {
        printf("incorrect third field, ");
      }
      printf("2 fields extracted: %s %s\n", string1, string2);
      break;
    }
    case 1:
    {
      if(n1!=-1) // this coma has been read
      {
        printf("incorrect second field, ");
      }
      printf("1 field extracted: %s\n", string1);
      break;
    }
    default:
    {
      printf("no field extracted\n");
    }
  }
}

int
main(void)
{
  parse_line("Hi, Hello, 123");
  parse_line("John, Doe, 45");
  parse_line("asd, asd, asd");
  parse_line("asd, asf");
  parse_line("asd, ");
  parse_line("asd");
  parse_line("");
  return 0;
}
/**
[Hi, Hello, 123] --> 3 fields extracted: Hi Hello 123
[John, Doe, 45] --> 3 fields extracted: John Doe 45
[asd, asd, asd] --> incorrect third field, 2 fields extracted: asd asd
[asd, asf] --> 2 fields extracted: asd asf
[asd, ] --> incorrect second field, 1 field extracted: asd
[asd] --> 1 field extracted: asd
[] --> no field extracted
**/