使用scanf解析字符串时的奇怪行为
在进行sscanf时,我遇到了相当奇怪的行为。目前正在使用c语言在windows 7计算机上工作 我有以下资料:使用scanf解析字符串时的奇怪行为,c,scanf,C,Scanf,在进行sscanf时,我遇到了相当奇怪的行为。目前正在使用c语言在windows 7计算机上工作 我有以下资料: if( sscanf( str, "%1[a-zA-Z]%31[a-zA-Z+.-]%n", &scheme[ 0 ], &scheme[ 1 ], &num_chars ) >= 1 ) { return( num_chars ); } str变量是一个较大的输入字符串,可能大于32个字符。 scheme变量声明为包装函数调用的参数,它是
if( sscanf( str, "%1[a-zA-Z]%31[a-zA-Z+.-]%n", &scheme[ 0 ], &scheme[ 1 ], &num_chars ) >= 1 )
{
return( num_chars );
}
str变量是一个较大的输入字符串,可能大于32个字符。
scheme变量声明为包装函数调用的参数,它是一个32个字符的数组
我可以很容易地用两个scanf或两个单独的变量来实现这一点。我只是好奇为什么这不起作用
编辑:在我执行此操作时,出现了一个包含“tel net”(正在测试“-”)的错误,它导致scheme字符串基本上没有可用字符 解决方案:
我弄明白了问题所在,其实根本不是scanf的问题 以下是我声明scheme变量的方式:
IOP_uri_scheme_type * scheme_str;
IOP_uri_方案_类型声明如下:
typedef char IOP_uri_scheme_type[ IOP_URI_MAX_SCHEME_SZ ]; // Size = 32
问题在于索引,scheme[1]实际上跳过了整个块(全部32个字节),而不是我所期望的字符。因此,从技术上讲,scanf一开始就编写正确(减去%n)
我可以解决这个问题的一种可能方法是,首先将scheme强制转换为(char*),或者直接操作指针值,取消引用它,或者不使用我不需要的指针
谢谢大家的帮助。看来您正试图在
sscanf
中使用正则表达式。据我所知,sscanf
对正则表达式没有任何支持。这里是我为这种情况制作的测试套件(为了可读性而减小了大小):
你能发布你的输出吗
请注意,您的程序有一个错误,因为如果第二个[
失败,%n
将不会被处理。如果返回值正好是2
,则只能返回num\u chars
关于“正则表达式”:根据C标准,在[]
说明符中使用连字符时会发生什么是由实现定义的。您的编译器(加上C库等)可能支持也可能不支持您正在尝试的用法。请查看您的编译器的scanf
文档,了解它对这种情况的说明
注意:我最初发布了一个回答,说读取重叠对象是未定义的-但是我认为这实际上是错误的,这是好的,因为参数是按顺序处理的(标准没有说它未定义)。发布问题时,
num_chars
是指针吗“获得奇怪的行为”-最好准确地描述您获得的行为以及您期望的结果(最好使用str
的确切示例演示意外输出)。您可以使用scanf执行类似于正则表达式的操作…事实上,这是基于一个。我的代码中分散了类似的表达式(解析uri)然而,这是我两次使用同一输出变量的唯一实例,我相信这就是问题所在。这编译并运行,只是没有填充输出字符串properly@user3638657,看一看。你可能会做一些看起来像这样的把戏,但我不确定你问题中的表达是否属于这些把戏tricks.scheme包含字母“t”\0”,然后在我执行一次运行后会变成垃圾。我还将提到我可以使用两个单独的变量作为输出,因此:sscanf(str,“%1[a-zA-Z]%31[a-zA-Z+.-]”,&scheme1[0],&scheme2[1]);这与scheme1中的“t”和“垃圾”+“el-net”一样有效“在scheme2.OK中,看起来您解决了问题(scheme
实际上不是32个字符的数组,而是指向一个字符的指针)。
#include <stdio.h>
int main()
{
char str[] = "tel-net";
char scheme[13] = { 0 };
int num_chars;
int result = sscanf( str, "%1[a-zA-Z]%11[a-zA-Z+.-]%n",
&scheme[ 0 ], &scheme[ 1 ], &num_chars );
printf("result = %d\n", result);
printf("scheme = '%s'\n", scheme);
printf("scheme = ");
for (int ii = 0; ii < sizeof scheme; ++ii)
printf("%02x ", (unsigned char)scheme[ii]);
printf("\n");
if ( result == 2 )
printf("num_chars = %d\n", num_chars);
return 0;
}
result = 2
scheme = 'tel-net'
scheme = 74 65 6c 2d 6e 65 74 00 00 00 00 00 00
num_chars = 7