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
我写了下面的代码来处理这种情况。
问题是我必须区分以下情况:
asd, asd, asd
asd, asf
但是在这两种情况下, scanf
returns value 2
这是正确的行为,因为据我所知,首先没有给出整数,其次没有第三个值。
因此,我需要一些帮助来设置扫描集,使其仅在包含一些文本和逗号 -> “文本”时作为正确的字符串数据传递。
或者也许我应该使用不同于 scanf()
. 的函数
使这项任务变得更加困难的是要求不使用任何由[]声明的或动态分配的额外数组。这必须仅使用这 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
**/
我有以下任务:
Read comma separated data in below format:
string1, string2, integer_number
e.g:Hi, Hello, 123 John, Doe, 45
我写了下面的代码来处理这种情况。 问题是我必须区分以下情况:
asd, asd, asd
asd, asf
但是在这两种情况下,scanf
returns value2
这是正确的行为,因为据我所知,首先没有给出整数,其次没有第三个值。 因此,我需要一些帮助来设置扫描集,使其仅在包含一些文本和逗号 -> “文本”时作为正确的字符串数据传递。 或者也许我应该使用不同于scanf()
. 的函数
使这项任务变得更加困难的是要求不使用任何由[]声明的或动态分配的额外数组。这必须仅使用这 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
**/