【问题标题】:Search string in file (C)在文件中搜索字符串 (C)
【发布时间】:2011-01-31 06:19:04
【问题描述】:

所以我的代码不起作用...

test.c:27: warning: passing argument 1 of ‘search’ from incompatible pointer type

这是 fgets 行。

我的代码打开一个文件,逐行读取文件,我正在尝试创建一个“搜索”函数,该函数将返回一个值,该值指示是否在文件的该行上找到了该字符串。

我的最终目标是实现一个搜索和替换程序。但是一步一步,嗯? 这是我目前所拥有的:

#include <stdio.h>
#include <string.h>

int search(const char *content[], const char *search_term)
{
    int t;

    for(t=0; content[t]; ++t){
        if(!strcmp(content[t], search_term)){
            return t; // found
        }
    }
    return 0; // not found
}


int main(int argc, char *argv[])
{
    FILE *file;
    char line[BUFSIZ];
    int linenumber=0;
    char term[20] = "hello world";

    file = fopen(argv[1], "r");
    if(file != NULL){
        while(fgets(line, sizeof(line), file)){
            if(search(line, term) != -1){
                printf("Search Term Found!!\n");
            }
            ++linenumber;
        }
    }       
    else{
        perror(argv[1]); 
    }

    fclose(file);
    return 0;
}

【问题讨论】:

  • 错误信息告诉你问题出在 search() 调用上,而不是 fgets() 调用上。注意你的编译器;它正在努力帮助你。
  • 开始代理调试!

标签: c arrays pointers replace


【解决方案1】:

改变

int search(const char *content[], const char *search_term)

int search(const char content[], const char *search_term)

编辑:

也改变:

if(!strcmp(content[t], search_term)){

if(!strcmp(&content[t], search_term)){

if(!strcmp(content + t, search_term)){

由于您使用strcmp 来查找匹配项,因此您将无法在文件中找到所有出现的搜索字符串。您只会在 search_string 中找到那些 end 的行。

例如:您的搜索字符串是“hello world”,并说文件有2 行:

I wrote hello world
hello world is good

在这种情况下,您的程序将只能找到第一次出现而不是第二次。

即使要找到此匹配项,也需要对您的代码进行一些更改:

fgets 读取的字符串有一个尾随换行符,你必须像这样去掉它:

while(fgets(line, sizeof(line), file)){
  line[strlen(line)-1] = 0;

此外,当搜索失败时,您将返回 0,应将其更改为 -1

【讨论】:

  • 如果我这样做了,我会得到:test.c:9: 警告:传递“strcmp”的参数 1 会在没有强制转换的情况下从整数生成指针
【解决方案2】:

如果我理解正确,您只是在以一种非常低效的方式重新实现 strstr() libc 函数。

【讨论】:

  • +1:因为“你的问题还不错,事实上你问的是”......除非是家庭作业;)
  • 是的,但我在这里遇到的问题是 strstr 不会搜索整个单词,而是首先搜索它匹配的任何内容。 (对吗?)例如,假设我有字符串“Hello Wonderful World”,使用 strstr("Hello Wonderful World", "Wonder"),但我是说字符串中存在“Wonder”吗? strstr 函数会说是并返回“Wonderful World”,这不是我想要的。
  • @chutsu:strstr 不返回字符串,它返回指向字符串中某个位置的指针,如果未找到搜索词,则返回 NULL。如果您想确定是否在该行中找到了该术语,只需将结果与 NULL 进行比较即可。
  • @chutsu,如果你使用strstr(或strcasestr)返回的指针并且只使用匹配“针”的长度(例如strlen("Wonder")),那么它将匹配你的搜索字符串“原位”。
【解决方案3】:

参数类型:

const char *content[]

不正确。使用:

const char *content  

/

#include <stdio.h>
#include <string.h>

int search(const char *content, const char *search_term)
{
    int t;

    for(t=0; content+t; ++t){
        if(!strcmp(content[t], search_term)){
            return t; // found
        }
    }
    return 0; // not found
}


int main(int argc, char *argv[])
{
    FILE *file;
    char line[BUFSIZ];
    int linenumber=0;
    char term[20] = "hello world";

    file = fopen(argv[1], "r");
    if(file != NULL){
        while(fgets(line, sizeof(line), file)){
            if(search((const char*)line, term) != -1){
                printf("Search Term Found!!\n");
            }
            ++linenumber;
        }
    }       
    else{
        perror(argv[1]); 
    }

    fclose(file);
    return 0;
}

【讨论】:

  • :(const char*) 行是做什么的??
  • 转换类型以便编译器不会抱怨,并以正确的方式处理它。提供强制转换是兼容类型(在内存结构中)你是安全的。否则,segfaults 和其他讨厌的事情就会随之而来...... C 的美丽。
【解决方案4】:

试试这个:

int search(const char *content, const char *search_term)

【讨论】:

    【解决方案5】:
    1. 如其他人所说,修复搜索参数。
    2. 您需要将content[t]的地址传递给strcmpcontent[t] 是一个字符,而不是一个字符串。
    3. 我认为您还有一些其他问题。例如return 0; - 也许是return -1

    4. 另外...我认为您可能需要使用 strncmp 来查找该行中的术语。

    例如。

    int search(char *content, const char *search_term)
    {
        int t;
    
        for(t=0; content[t]; ++t){
            if(!strncmp(&content[t], search_term, strlen(search_term))){
                return t; // found
            }
        }
        return -1; // not found
    }
    

    【讨论】:

      【解决方案6】:

      试试这个方法:

      int search(const char *content, const char *search_term)
      {
         char *result = strstr(content, search_term);
         if(result == NULL) return 0;
         return (int)(result - content);
      }
      

      resultcontent 之间的区别正是找到结果的索引。我相信这就是您要找的东西?

      我认为虽然还有改进的余地。您不想在不匹配时返回0,因为这可能会与第一个字节位置的匹配混淆,这也是0。如果必须返回整数,则返回 -1

      if(result == NULL) return -1;
      

      不过,更进一步,您可以看到此方法只是对您以后甚至不会使用的功能的包装。如果你在main 中关心的只是是否找到了字符串,那么完全删除这个函数并像这样写main

      int main(int argc, char *argv[])
      {
         FILE *file;
         char line[BUFSIZ];
         int linenumber = 1;
         char term[20] = "hello world";
      
         file = fopen(argv[1], "r");
         if(file != NULL) {
            while(fgets(line, sizeof(line), file)){
               if(strstr(line, term) != NULL) {
                   printf("Search Term Found at line %d!\n", linenumber);
               }
               ++linenumber;
            }
         }
         else {
            perror(argv[1]);
         }
      
         fclose(file);
         return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2011-01-12
        • 2010-12-10
        • 2015-06-08
        • 2012-10-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-14
        • 2021-10-20
        相关资源
        最近更新 更多