我有这样的结构
struct tm1
{
char buf[80];
int val;
} pl;
我想从文件中填充此结构,该文件包含当前时间和一个值。喜欢这个
Mon Dec 4 19:36:23 2017 98
现在我想做fscanf的时间和文件中的值98,并将这些值放在结构中(时间应该转到结构成员buf,值即98应该转到结构成员val。)< / p>
现在问题是fscanf在第一个空格处终止,所以为了解决这个问题我尝试了
fscanf(infile,"%[^\n]",pl.buf);
但是从文件中执行此值后98也将转换为结构成员buf ..
如何在结构成员buf中存储时间,在结构成员val中存储值98?
答案 0 :(得分:3)
最好使用fgets()
来获取输入行。然后可以使用sscanf()
来解析输入。
您可以将分配抑制(*
)与扫描集指令(%[]
)结合使用,以忽略日期的第一部分:%*[^0-9] %*d
。扫描时间,然后再次使用抑制忽略年份。请注意扫描集中破折号的行为,例如%*[^0-9]
是实现定义的,但这通常表现为预期范围。一个完全可移植的替代方案是使用:%*[^0123456789]
代替。
以下是一个示例程序:
#include <stdio.h>
#include <stdlib.h>
struct tm1
{
char buf[80];
int val;
};
int main(void)
{
struct tm1 p1;
FILE *fp = fopen("file.dat", "r");
if (fp == NULL) {
perror("Unable to open file");
exit(EXIT_FAILURE);
}
char buffer[4096];
while (fgets(buffer, sizeof buffer, fp)) {
if (sscanf(buffer, "%*[^0-9] %*d %79s %*d %d", p1.buf, &p1.val) == 2) {
printf("%s, %d\n", p1.buf, p1.val);
}
}
return 0;
}
节目输出:
19:36:23, 98
我似乎误解了OP的问题。上述解决方案不会将整个日期存储在buf
的{{1}}字段中。为了存储整个日期,最好在日期和最终值之间设置一些分隔符以帮助解析输入行。如果没有这样的分隔符,上面提到的技术可能仍然有用。
struct
指令存储到目前为止从输入流中读取的字符数。这可用于标识示例输入中日期之后的位置。考虑:
%n
此处sscanf(buffer, "%*[^0123456789] %*d %*s %*d%n", &tail)
忽略每个日期组件,并将字符数存储在sscanf()
中,这相当于tail
中日期之后的字符索引。可以通过扫描再次使用buffer[]
来获取最终值:
sscanf()
然后可以在日期之后放置一个空终止符,允许将日期复制到sscanf(buffer + tail, "%d", &p1.val)
的相应字段。
这是另一个示例程序。解析在这里不是防弹,但它应该处理格式良好的数据。请注意,当struct
太大时,会跳过该行。这表示日期字符串不适合tail
。
p1.buf
以下是输入文件示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct tm1
{
char buf[80];
int val;
};
int main(void)
{
struct tm1 p1;
FILE *fp = fopen("file.dat", "r");
if (fp == NULL) {
perror("Unable to open file");
exit(EXIT_FAILURE);
}
char buffer[4096];
while (fgets(buffer, sizeof buffer, fp)) {
int tail = 0;
if (sscanf(buffer, "%*[^0123456789] %*d %*s %*d%n", &tail) == 0) {
if ((unsigned) tail < sizeof p1.buf
&& sscanf(buffer + tail, "%d", &p1.val) == 1) {
buffer[tail] = '\0';
strcpy(p1.buf, buffer);
printf("%s, %d\n", p1.buf, p1.val);
}
}
}
return 0;
}
以下是程序输出:
Mon Dec 4 19:36:23 2017 98
Tues Dec 5 19:36:28 2017 99
Wed Dec 6 19:36:21 2017 95
Thur Dec 7 19:36:23 2017 89
Fri Dec 8 19:36:20 2017 93
Sat Dec 9 19:36:22 2017 oops! 95
Sun Dec 10 19:36:23 2017 98
Sun Dec 10 19:36:23 2017 98
Mon Dec 11 19:36:25 2017 97