【问题标题】:finding reoccuring string in I/O stream -C?在 I/O 流 -C 中查找重复出现的字符串?
【发布时间】:2014-04-22 12:07:29
【问题描述】:

我对 C 很陌生。我正在尝试编写一个在 I/O 流中查找字符串的代码,但我不明白我做错了什么。我知道错误可能在大的while循环中(在下面的代码中)。 我希望函数从流的开头返回位置(以字节为单位),如果由于某种原因失败,则返回 -1。对于我尝试使用的任何文件,它只会一直返回 -1。

long find_string(const char *str, const char *filename, long offset)
{
FILE *f = fopen(filename, "r");
if (!f){
    return -1;
}

int s=0,c;

c = fgetc(f);
if(c == EOF){
    return -1;
}

char *check = malloc(sizeof(char));

fseek(f, 0L, SEEK_END); // Sees and stores how long the file is
long sz = ftell(f);
fseek(f, 0L, SEEK_SET);

if(fseek(f, offset,SEEK_SET) != 0){ // finds the position of offset
    return -1;
}


while(fgetc(f) != EOF){
    c = fgetc(f);
    if(c == str[0] && ftell(f) < sz){
        check[0] = c;
        offset = ftell(f);
        }

        s++;
        for (unsigned int r=1; r < (strlen(str));r++){
            c = fgetc(f);
            if(c == str[s]){
                    check = realloc(check, sizeof(char)*s);
                    check[s] = c;
                    s++;
            }                   
        }

    if(strcmp(check, str)==0){
        free(check);
        fclose(f);
        break;

    }
    else{
        check = realloc(check, sizeof(char));
        offset = -1;
    }
}
return offset;}  

非常感谢任何帮助

【问题讨论】:

  • 哎哟。我不知道您的具体问题是什么,但是您已经使这比必须的要难 3 倍。考虑重新考虑整个事情。
  • 为了教你如何钓鱼,而不是为所有错误返回 -1,你可以返回不同的值。这至少会告诉你函数的哪个部分失败(并且也会帮助我们)
  • “我做错了什么”——基本上就是所有事情。

标签: c realloc fseek ftell


【解决方案1】:

如果您简单地对整个文件进行内存映射并在其上运行标准字符串搜索算法,这会容易得多。

内存映射见:Linux - Memory Mapped File

字符串搜索代码见:strstr() for a string that is NOT null-terminated

【讨论】:

    【解决方案2】:

    请检查评论更新的行

    long find_string(const char *str, const char *filename, long offset)
    {
    FILE *f = fopen(filename, "r");
    if (!f){
        return -1;
    }
    
    int s=0,c;
    
    c = fgetc(f);
    if(c == EOF){
        return -1;
    }
    
    char *check = malloc(sizeof(char));
    
    fseek(f, 0L, SEEK_END); // Sees and stores how long the file is
    long sz = ftell(f);
    fseek(f, 0L, SEEK_SET);
    
    if(fseek(f, offset,SEEK_SET) != 0){ // finds the position of offset
        return -1;
    }
    
        c = fgetc(f); // Updated
    while(c != EOF){ // Updated
        if(c == str[0] && ftell(f) < sz){
            check[0] = c;
            offset = ftell(f);
            }
    
            s++;
            for (unsigned int r=1; r < (strlen(str));r++){
                c = fgetc(f);
                if(c == str[s]){
                        check = realloc(check, sizeof(char)*s);
                        check[s] = c;
                        s++;
                }                   
            }
    
        if(strcmp(check, str)==0){
            free(check);
            fclose(f);
            break;
    
        }
        else{
            check = realloc(check, sizeof(char));
            offset = -1;
        }
        c = fgetc(f); //Updated
    }
    return offset;}  
    

    由于您在查看条件和开始时使用 fgetc,因此实际上是将文件的第二个字符与 str 的第一个字符进行比较。更新并检查。

    【讨论】:

      猜你喜欢
      • 2017-10-23
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      相关资源
      最近更新 更多