-4

当通过命令行给出参数以搜索文件中由文件中的某个分隔符分隔的字符串时,我们在 C 中使用什么命令/代码?

char searchString[20];
char *src;
f = fopen("passwd", "r");
if (f == NULL)
{
    printf("Error while opening the file");
    //exit(1);
}
while (fgets(ch, sizeof ch, f)!= NULL)
{
    /*printf("%s\n", ch); */

    for (j = 1, str = ch; ; j++, str= NULL)
    {
         char *token = strtok_r(str, ": ", &saveptr);
         if (token == NULL)
             break;
         //printf("%s---\n---", token);
         //printf("%s",token);
         //printf("%s",strlen(token));

         if (strstr(token, argv[2]) != NULL)
         {
             printf(token);
         }

    }
    //src = strstr(token, argv[2]);
    //printf ("String matched");    



 }


fclose(f);
4

1 回答 1

1

如果您刚刚开始,您可以将此问题分解为两个步骤。

  1. 每次看到分隔符时,将文件的内容分成几部分。您可以编写一个循环来查看文件的每个字符,并查看该字符是否与分隔符匹配。如果是这样,那么您将比较从文件开头(或找到的最后一个分隔符)到您找到的新分隔符(或文件结尾)的内容。作为替代方案,您可以使用strtok函数在分隔符处为您拆分文件内容。

  2. 在分隔符处拆分文件内容后查看每个项目。这可能只是使用strcmpstrncmp比较在上一步中找到的条目(或通过 找到的标记strtok)。一般来说,使用strncmp更安全,因为如果用户提供的字符串不是以空值结尾的,则不会有程序崩溃的风险。strstr如果您想找到匹配的子字符串,也可以使用。

现在您已经包含了代码,看起来您有一个不需要的 for 循环。相反,您可以像这样使用带有 strtok 的 while 循环:

char *token = strtok (str,": ");
while (token != NULL)
{
    if (strstr(token, argv[2]) != NULL)
    {
        printf(token);
    }
    token = strtok (NULL, ": ");
}

但是,此代码假设您有两个分隔符,:并且. 相反,如果您想在冒号和空格的多字符分隔符上进行拆分,则可以参考this other stack overflow question about split a string on multiple characters in c

一个问题strtok是它修改了正在解析的字符串。这意味着如果您想要字符串的原始内容,则需要在其他地方保存该字符串的副本。这可以通过使用该strdup函数创建字符串的副本来完成。执行此操作的代码如下所示:

char *dup = strdup(ch);

要说明如何更清楚地将其添加到代码中,您将执行以下操作:

char* dup;
while (fgets(ch, sizeof ch, f)!= NULL)
{
    dup = strdup(ch);

然后在你的检查使用中strstr,你可以调用printf(dup).

那,正如@Gangadhar 指出的那样,您可能不需要在分隔符处拆分(除非您要搜索的内容包含它们,这意味着如果删除分隔符将找不到任何东西)。如果是这种情况,只需使用strstr并且不要在分隔符处拆分行,那么指向的字符串ch将不会被修改并且可以按原样打印。如果您在行尾使用最后一个换行符而不是在 printf 中包含一个换行符,则他的代码中可能不需要删除换行符;采用这种方法的唯一问题是,如果一行不以换行符结尾。

while (fgets(ch, sizeof ch, fp)!=NULL)
{
    if (strstr(ch,argv[2])!= NULL)// check whether argumenttis in line
    {
        printf("%s\n",ch); // if found print line
    }
}

如果要从字符串的开头计算要搜索的当前标记的开头的偏移量,可以使用字符串中的字符存储在连续内存地址中的事实。&ch[0]因此,您可以从您正在查看的当前标记的地址中减去原始字符串中第一个字符的地址token。这可能看起来像一行代码:

int offset = (int) (token - &ch[0]);
于 2013-10-12T10:05:35.387 回答