为学校做一些项目,我遇到了以下问题:
<link data-require="bootstrap-css" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" />
<link data-require="bootstrap@*" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
读取与预期值不同的值。
我想读这样的东西:
sscanf
这是我目前使用的代码:
1 0 185336079 0 0 168231418 -256 0 255 1
2 0 185336079 -256 0 168231418 -256 0 255 2
3 0 185336079 -256 0 168231418 -256 0 255 3
4 0 185336079 0 0 0 0 0 255 4
以上代码生成的输出如下:
FILE *fd = open_fd("/proc/firewall", "r");
while ((read = getline(&line, &len, fd)) != -1) {
sscanf(line, "%d %c %d %d %d %d %d %d %c %c\n", &num,
&rule_u.inbound_outbound,
&rule_u.source_ip,
&rule_u.source_netmask,
&rule_u.source_port,
&rule_u.destination_ip,
&rule_u.destination_netmask,
&rule_u.destination_port,
&rule_u.protocol,
&rule_u.action);
printf("scanf read rule action : %c\n", rule_u.action);
printf("sscanf whole line:\n%s\n",line);
convert_rule_from_u();
print_rule();
}
预期输出应如下:
scanf read rule action : 5
sscanf whole line:
1 0 185336079 0 0 168231418 -256 0 255 1
scanf read rule action : 5
sscanf whole line:
2 0 185336079 -256 0 168231418 -256 0 255 2
scanf read rule action : 5
sscanf whole line:
3 0 185336079 -256 0 168231418 -256 0 255 3
scanf read rule action : 5
sscanf whole line:
4 0 185336079 0 0 0 0 0 255 4
scanf read rule action : 1
sscanf whole line:
1 0 185336079 0 0 168231418 -256 0 255 1
scanf read rule action : 2
sscanf whole line:
2 0 185336079 -256 0 168231418 -256 0 255 2
scanf read rule action : 3
sscanf whole line:
3 0 185336079 -256 0 168231418 -256 0 255 3
scanf read rule action : 4
sscanf whole line:
4 0 185336079 0 0 0 0 0 255 4
rule_u struct
我做错了什么?
答案 0 :(得分:2)
在尝试使用格式说明符"255 0"
阅读"%c %c"
时,代码在每行末尾都有问题。
这会扫描并保存字符'2'
和第一个'5'
。 OP希望将整数保存为255和0的所需结果。
使用"%hhu %hhu"
读取数字文本并将其整数另存为unsigned char
。
答案 1 :(得分:1)
通常,在scanf()
系列函数的格式字符串中使用尾随空格是一个坏主意 - 有关详细信息,请参阅Trailing blank in scanf()
format string。如果函数是sscanf()
或其中一个亲戚,从字符串而不是文件流中读取,那么它不是灾难。
但是,您还遇到了问题,即最后的第二个%c
未读取所有255
- 您需要%d
(或者{最后一列的{1}}或%hhd
),应该审核所有其他%c列;也许他们也应该是数字?
所以你说它应该是这样的:
%hhu
- 可以吗?我认为它之前阅读了整个sscanf(line, "%d%hhu%d%d%d%d%d%d%hhu%hhu",...
;我正在玩它,它正在工作,或者至少看起来像它。
转换规范之间的空格是可以的;它们使它更具可读性。字符串末尾的换行符意味着&#34;读取空白区域,直到找到不是空格&#34;的东西,如果输入来自(磁盘)文件或字符串,则可以。如果输入来自终端,管道,FIFO,套接字,那将是一场灾难。
对255
的调用不会返回,直到输入中出现下一条消息为止;它需要除换行符或空格或制表符之外的其他内容来表示&#34;全部&#34;。那可能不是你想要的。
示例数据中的最后一个字段显然不是单个字符。您可能需要一个适合无符号字符的数字,因此scanf()
是合适的。其他两个%hhu
列仅在数据中保留零,但如果它们可以包含大于9的数字,则需要%c
。
&#39;入站/出站&#39;列可能是0或1,因此%hhu
可能就行了(但请注意,值为%c
和'0'
,而不是'1'
和{{ 1}}!)。您知道数据(或需要知道数据) - 您的电话。
我注意到你的结构浪费了相当多的空间。开头的一个字节字段后面有3个字节的填充,最后还有两个字节的填充。考虑移动彼此相邻的三个无符号字符字段以保存每个结构4个字节(您仍然有1个填充字节,但这是5的改进)。想一想这是否重要(可能性并不重要)。
此外,您应该测试0
- 或1
的返回值,以确保输入正确。
sscanf()
答案 2 :(得分:0)
你的倒数第二个转换说明符是%c
,它只需要一个字符。您的输入有3:"255"
(或某些此类内容)。
因此,您正在偏离轨道,并且每一行都是从最后一行读取的项目,而不是之前的迭代。