C scanf()从控制台读取逗号分隔值(字符串和整数)的扫描集
我有以下任务: 读取以下格式的逗号分隔数据:C scanf()从控制台读取逗号分隔值(字符串和整数)的扫描集,c,string,scanf,stdin,C,String,Scanf,Stdin,我有以下任务: 读取以下格式的逗号分隔数据: string1、string2、整数 e、 g: 我写了下面的代码来处理这个案例。 问题是我必须区分以下情况: asd、asd、asd asd,asf 但在这两种情况下,scanf返回值2,这是正确的行为,因为据我所知,首先没有给出整数,其次没有第三个值。 因此,我需要一些帮助来设置扫描集,当它由一些文本和逗号->文本组成时,如何将其设置为仅作为正确的字符串数据传递。 或者我应该使用与scanf()不同的函数 使此任务更加困难的是要求不要使用[]
string1、string2、整数
e、 g:
我写了下面的代码来处理这个案例。
问题是我必须区分以下情况:
asd、asd、asd
asd,asf
但在这两种情况下,scanf
返回值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;
}
#包括
#包括
int main()
{
charstring1[20];
charstring2[20];
整数;
printf(“类型数据:\n”);
int ret_val=scanf(“%[a-zA-Z]、%[a-zA-Z]、%d”、字符串1、字符串2和编号);
如果(返回值!=3){
printf(“返回值%d”,返回值);
返回1;
}
printf(“%s%s%d\n”,字符串1,字符串2,数字);
返回0;
}
我通常依赖于*scanf()
的技巧是使用%n
来检测输入到现在为止是否已被读取;当您需要一些文字时(在*scanf()
的结果中不考虑这些文字),这一点特别有用
请注意,根据man 3 sscanf
,%n
在*scanf()
的结果中不被考虑
/**
gcc-std=c99-o程序c程序c.c\
-学究式-墙壁-Wextra-Wconversion\
-Wc++-compat-Wwrite字符串-Wold样式定义-Wvla\
-g-O0-UNDEBUG-fsanizize=地址,未定义
**/
#包括
无效的
解析_行(常量字符*行)
{
printf(“[%s]-->”,第行);
char string1[20]=“”;
字符字符串2[20]=“”;
整数=-1;
int n1=-1,n2=-1;
int r=sscanf(行“%[a-zA-Z],%n%[a-zA-Z],%n%d”,
第1条和第1条、第2条和第2条、第2条和第2条);
开关(r)
{
案例3:
{
printf(“提取的3个字段:%s%s%d\n”,字符串1,字符串2,编号);
打破
}
案例2:
{
if(n2!=-1)//此昏迷已被读取
{
printf(“不正确的第三个字段,”);
}
printf(“提取的2个字段:%s%s\n”,字符串1,字符串2);
打破
}
案例1:
{
如果(n1!=-1)//此昏迷已被读取
{
printf(“第二个字段不正确,”);
}
printf(“提取的1个字段:%s\n”,string1);
打破
}
违约:
{
printf(“未提取字段”);
}
}
}
int
主(空)
{
解析行(“嗨,你好,123”);
解析线(“John,Doe,45”);
解析行(“asd、asd、asd”);
解析行(“asd,asf”);
解析_行(“asd”);
解析线(“asd”);
解析_行(“”);
返回0;
}
/**
[Hi,Hello,123]-->提取的3个字段:Hi,Hello 123
[John,Doe,45]-->提取的3个字段:John Doe 45
[asd,asd,asd]-->第三个字段不正确,提取了两个字段:asd asd
[asd,asf]-->提取的两个字段:asd asf
[asd,]-->第二个字段不正确,提取了1个字段:asd
[asd]-->提取的1个字段:asd
[]-->未提取任何字段
**/
那么这两种情况下会发生什么?asd、asd、asd-应该认识到只有string1和string2被正确读取。asd,asf-应该认识到只有string1被正确读取scanf
将返回2,因此这意味着只有string1和string2被正确读取。。。还有。。。?也许我不明白你想要什么…每个字符串都必须由commaNo完成,因为没有你可以使用的“函数”。你必须自己编写代码。
#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;
}
/**
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
**/