从包含空格的文件中读取字符串,并在C中搜索给定字符串的文件

时间:2015-08-30 16:07:50

标签: c string

我正在尝试在文本文件中搜索字符串,当文本文件如下所示:

"Naveen; Okies
PSG; Diploma
SREC; BECSE"

当输出控制台询问输入字符串时,当我键入naveen时,它将导致打印Okies,当我键入PSG时,它将打印文凭。这工作正常,因为我使用下面的代码:

fscanf(fp, "%[^;];%s\n", temp, Mean);

但是下面的文本文件不起作用,

"Naveen; Okies Is it working
PSG; Diploma Is it working
SREC; BECSE Is it working"

我的代码仍然给我Okies作为Naveen的输出,我需要" Okies它是否正常工作"作为输出。

所以我将我的代码更改为fscanf(fp, "%[^;];%[^\n]s", temp, Mean);我得到的地方' Okies它是否正常工作'作为输出。但是对于搜索字符串,它不会搜索下一行。当我搜索PSG时,我没有得到任何输出。

请帮助我理解我的问题。

2 个答案:

答案 0 :(得分:3)

侧杆

请注意,您应该检查fscanf()的返回值。

你说你试过了:

fscanf(fp, "%[^;];%[^\n]s", temp, Mean);

这可能是一种混乱的格式。最后的s正在输入中查找文字s,但它永远不会被找到,并且您无法知道它未找到。 %[^\n]扫描集转换规范会查找一系列非换行符'。它只会在下一个字符是换行符或EOF时停止。因此,s是一个永远不会匹配的文字s。但是fscanf()的返回值是成功转换的次数,可能是2.您无法确定是否已读取s。它应该从格式字符串中删除。

主要答案

要解决您的主要问题,%s格式会在第一个空格处停止。如果您想处理整行,请不要使用%s。使用POSIX getline()或标准C fgets()来读取该行,然后对其进行分析。

您可以使用strtok()进行分析。我不会在任何库代码中执行此操作,因为调用strtok()的任何库函数都不能从也可能使用strtok()的代码中使用,也不能调用该函数的任何函数,或者它直接或间接调用的函数之一使用strtok()strtok()函数有毒 - 您一次只能在一个函数中使用它。这些评论不适用于 strtok_r()或类似的Microsoft提供的变体strtok_s() - 与C11的可选附件K中定义的strtok_s()类似但不同。带后缀的变体是可重入的,不会像strtok()那样使系统中毒。

我可能在这种情况下使用strchr();你也可以看看 strstr()strpbrk()strspn()strcpsn()。所有这些都是标准的C函数,自C89 / C90以来就一直存在。

答案 1 :(得分:0)

我认为Jonathan已经很好地解释了它,但是,我正在添加一个示例来展示如何处理您的示例以用于学习目的。请记住,您可能想要更改某些功能,因为我使用了已弃用(不安全)的功能,这可能是您的练习。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main(int argc, char *argv[]) {
    FILE *fp = NULL;
    char szBuffer[1024] = { '\0' };
    char szChoice[256] = { '\0' };
    char szResult[256] = { '\0' };

    if ((fp = fopen("test.txt", "r")) == NULL) {
        printf("Error opening file\n");

        return EXIT_FAILURE;
    }

    printf("Enter your choice: ");
    scanf("%s", &szChoice);

    while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
        if (!strncmp(szBuffer, szChoice, strlen(szChoice))) {
            char *pch = szBuffer;

            pch += (strlen(szChoice) + 1);

            printf("Result: %s", pch);
        }
    }

    getchar();

    return EXIT_SUCCESS;
}