对未知数量的变量使用sscanf

对未知数量的变量使用sscanf,c,scanf,C,Scanf,对于学校作业,我必须读入至少有一个但最多有三个变量(命名命令、一个和两个)的字符串。字符串的开头总是有一个字符,但后面可能有整数,也可能没有整数。格式可以类似于以下任何一种: i5 17 i 3 P d 4 我正在使用fgets从文件中读取字符串,但处理它时遇到问题。我一直在尝试使用sscanf,但我正在读取一个只有一个或两个变量而不是三个变量的字符串 我是否应该使用其他功能 或者有没有一种方法可以格式化sscanf来完成我需要的工作 我尝试了sscanf(buffer,%c%d%d),c

对于学校作业,我必须读入至少有一个但最多有三个变量(命名命令、一个和两个)的字符串。字符串的开头总是有一个字符,但后面可能有整数,也可能没有整数。格式可以类似于以下任何一种:

i5 17
i 3
P
d 4
我正在使用fgets从文件中读取字符串,但处理它时遇到问题。我一直在尝试使用sscanf,但我正在读取一个只有一个或两个变量而不是三个变量的字符串

  • 我是否应该使用其他功能
  • 或者有没有一种方法可以格式化sscanf来完成我需要的工作

我尝试了sscanf(buffer,%c%d%d),command,one,two)和一些变体,但都没有成功。

sscanf
可能要完成这项任务,具体取决于输入的确切要求和范围

这里的关键是
scanf
系列函数返回一个有用的值,该值指示进行了多少次转换。这可以小于零:如果输入结束或I/O错误发生,甚至在尝试第一次转换之前,可以返回值
EOF
(负值)

请注意,
%c
转换说明符不会生成以null结尾的字符串。默认情况下,它只读取一个字符并通过参数指针存储。例如

char ch;
sscanf("abc", "%c", &ch);
这将把字符
'a'
写入
ch

除非您有一个铁一般的保证,第一个字段总是一个字符宽,否则最好用
%s
将其作为字符串读取。始终对
%s
使用最大宽度,以避免目标缓冲区溢出。例如:

char field1[64]; /* one larger than field width, for terminating null */
sscanf(..., "%63s", field1, ...);

sscanf
不会对整数执行任何溢出检查。如果使用
%d
扫描不适合
int
的大负值或正值,则根据ISO C,该行为只是未定义。因此,与
%s
一样,
%d
最好与字段宽度限制一起使用。例如,
%4d
用于读取四位数年份。四位十进制数字不会溢出
int

sscanf
可能由该任务决定,具体取决于输入的确切要求和范围

这里的关键是
scanf
系列函数返回一个有用的值,该值指示进行了多少次转换。这可以小于零:如果输入结束或I/O错误发生,甚至在尝试第一次转换之前,可以返回值
EOF
(负值)

请注意,
%c
转换说明符不会生成以null结尾的字符串。默认情况下,它只读取一个字符并通过参数指针存储。例如

char ch;
sscanf("abc", "%c", &ch);
这将把字符
'a'
写入
ch

除非您有一个铁一般的保证,第一个字段总是一个字符宽,否则最好用
%s
将其作为字符串读取。始终对
%s
使用最大宽度,以避免目标缓冲区溢出。例如:

char field1[64]; /* one larger than field width, for terminating null */
sscanf(..., "%63s", field1, ...);

sscanf
不会对整数执行任何溢出检查。如果使用
%d
扫描不适合
int
的大负值或正值,则根据ISO C,该行为只是未定义。因此,与
%s
一样,
%d
最好与字段宽度限制一起使用。例如,
%4d
用于读取四位数年份。四位十进制数字不会溢出
int

sscanf()
返回它成功扫描的指定值的数目。要理解为什么会出现segfaults,需要提供具有代表性的代码。它认为通常不应该使用
sscanf()
来解析文件中的一行,但实际上可以执行类似
switch的操作(sscanf(line,“%c%d%d”、&character、&integers[0]、&integers[1]){案例1:/*只是第一个char * /中断;案例2:/*第一char和一个整数*/Burd;案例3:/*完整的项目*/Bug;。对于一般情况下,一行上的值个数没有一个小的上界,请考虑.<代码> sScScf()中的技术。
返回它成功扫描的指定值的数目。要理解为什么会出现segfaults,您需要提供代表性的代码。它认为通常不应该使用
sscanf()
解析文件中的一行,但实际上您可以执行类似于
开关(sscanf(line),%c%d%d)的操作,&字符,&整数[0],&整数[1])){案例1:/*只是第一个char * /中断;案例2:/*第一个字符和一个整数*/Burd;案例3:/*完整的项*/Burn;。对于一般情况下,一行上的值个数没有一个小的上界,请考虑其中的技术。lt.@Kaz是正确的。令人困惑的是它的语义与
printf()不同
说明符。@Kaz-您没有指定宽度。对于
%c
原样,宽度默认为
1
。@Peter感谢您指出这一点,但我觉得,由于我在回答的第一次修订中以及在回复您的评论中已经说过宽度默认为1,所以“
%c
宽度默认为1"现在已经被活活打死了。也许它是如此重要以至于需要重复?非常感谢——我也有一个指针的问题,但这肯定为我澄清了函数,我能够解决问题并正确存储变量。@Peter它实际上可以读取多个字符,由with决定。一个是默认值。@Kaz是正确的。令人困惑的是,它的语义与
printf()
说明符不同。@Kaz