C 要检查文件中是否存在值

C 要检查文件中是否存在值,c,file,C,File,这里我有一个包含一些信息的文件,我想检查文件中是否存在一些标记值。如果存在,那么我想检索这些值 这里标签的数量是固定的,标签的长度不会超过16,标签值的长度几乎是固定的,它不会超过10个字节 从下面的文件中,我想检查内核标记值是否存在,FS标记值是否存在,等等 我想检查:(冒号)之后是否存在所有值 我的文件包含这样的文本 KERNEL:2.31 FS:3.4 XLOADER:1.1 UBOOT:2.2 还是像这样 KERNEL:2.31 FS: XLOADER:1.3 UBOOT: Valu

这里我有一个包含一些信息的文件,我想检查文件中是否存在一些标记值。如果存在,那么我想检索这些值

这里标签的数量是固定的,标签的长度不会超过16,标签值的长度几乎是固定的,它不会超过10个字节

从下面的文件中,我想检查
内核
标记值是否存在,
FS
标记值是否存在,等等

我想检查
(冒号)之后是否存在所有值

我的文件包含这样的文本

KERNEL:2.31
FS:3.4
XLOADER:1.1
UBOOT:2.2
还是像这样

KERNEL:2.31
FS:
XLOADER:1.3
UBOOT:
Value = 2.31
我正在使用这个代码

#include <stdio.h>

int main() {

    FILE *infile = fopen("example.txt", "r");

    char buffer[256];
    char value[128];

    while (fgets(buffer, sizeof(buffer), infile))
        if (1 == sscanf(buffer, "KERNEL:%s", value)) {
            printf("Value = %s\n", value);
        }
    return 0;
}
我从数据文件中读取行,然后我想解析每个标记的值(表示希望标识值是否存在)


因此,这是一个很好的方法,任何人都可以向我推荐吗?

鉴于您的示例,我尝试的第一种方法是:

Read a line
Remove all whitespace
   If the last character on the line is a colon <do something>
Else
    Do something else
读一行
删除所有空白
如果行上的最后一个字符是冒号
其他的
做点别的

您的问题没有明确说明文件所处的环境(或者在我开始回答时没有)。据推测,它是应用程序可以通过某种方式找到的文本文件

您没有指定内容(标记)是否应该固定,文件是否可以包含其他信息,是否有注释约定,是否允许空白行,如果标记完全丢失会发生什么,如果文件中有意外标记会发生什么,如果标记重复会发生什么(版本相同,版本不同)。标记是否区分大小写;标记前是否允许前导空格;版本前是否允许前导空格;版本后是否允许前导空格?版本号中允许哪些字符?这些都是重要的细节

让我们假设名称列表是固定的。让我们假设标记长度不超过7(终端为空的为8)。让我们假设版本号总共不超过15个字符(允许终端为空的为16)。让我们假设您需要记录找到的标记和找到的版本

在这种情况下,最终的数据结构有点像这样:

typedef struct VersionInfo
{
    char     tag[8];
    char     version[16];
} VersionInfo;

static VersionInfo version_data[] =
{
    { "KERNEL",  "" },
    { "FS",      "" },
    { "XLOADER", "" },
    { "UBOOT",   "" },
};
显然,有了这个基本结构,您可以编写一个函数来读取数据文件中的每一行,丢弃任何注释或空行(如果合适的话)
对于这一点,预期的行是短的。您可能应该抱怨行太长,并决定是否忽略它们或停止处理。您可以在
version\u data
数组中查找每个标记,当您找到一个标记时,记下它之前是否被找到,然后在该行上查找版本信息,然后单击c将其复制到
version\u数据
数组的相应部分

您可以使用“预期版本”字段和“实际版本”字段扩展该结构。这将允许您根据找到的版本决定要执行的操作。例如,您可能有与允许的版本相关的范围,这些范围基于编译程序时已知的内容。您可以允许编译的程序用3.0.3来运行3.0.4和更高版本,也许你甚至愿意使用3.0.0和更高版本,但不是任何版本2

请注意,版本比较本身就是一门艺术。例如,版本3.0.3、3.1.2、3.6、3.6.1、3.6.1.2和3.10.0可能应按版本号的升序处理。使用
strcmp()
无法实现这一点(它将
3.10.0
置于所有
3.6
版本之前)


我看到您的示例代码使用带有固定字符串的
sscanf()
。这可能会将您与固定顺序联系在一起,当然不会像数据结构允许的那样灵活。如果使用
sscanf()
,我希望使用如下格式:

if (sscanf(buffer, "%7s:%15s", tag, version) != 2)
    ...something up with the input line...
...process tag and version that you did find...
可以使用字符类符号优化扫描:

if (sscanf(buffer, "%7[A-Z]:%15[0-9.]", tag, version) != 2)

这只接受标记中的大写字母,并且只接受版本信息中的数字和点(但对版本“.0…0…0”非常满意,您可能不应该将其视为有效).

在这里,但我如何将内核值的数据填充到结构中。我的第一个目标是检查值是否存在。如果为空,则我将不做任何事情,如果存在,则将其保留并继续。我将在接收方解析此文件。无需在此解析。从第行中,我希望检索特定标记的值,而不是我上面的代码如果你不想保留你读到的信息,不要把它复制到结构中。事实上,你可以将结构简化为一个简单的标签列表。你甚至可以按照你希望它们出现的顺序来放置它们。可能性是无穷的。不清楚你为什么要读取文件并检查是否如果你不记录某个值的存在或不存在,那么该值存在或不存在。因为该检查的动机目前难以理解(或者,至少,我没有计算),很难给出一个很好的答案。在这里,对于发送方,我想检查这些值是否存在,接收方,我将解析它们并将它们放入结构中。因此,我可以从那里阅读。请加入这里“在Stack Exchange,我们坚持要求提问的人在他们的问题上投入一些精力,而我们在这方面有点蠢。”()