【问题标题】:Get the text before and after strstr in C获取C中strstr前后的文本
【发布时间】:2018-11-30 16:28:27
【问题描述】:

我需要能够提取子字符串前后的字符,目前我有以下代码:

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

int main(int argc, char *argv[]){

   char *text = (char *) malloc (10000000);
   char *word = argv[1];
   int rep;

   FILE *f;

   if(argc < 2)
   {
       printf("Usage: GET <website> | ./word_counter <word>\n");
       exit(1);
   }

   fread(text, 100, 10000000, stdin);

   const char *tmp = text;

   f = fopen("output.txt", "w");
   fprintf(f, "%s\n", "REPS");

   while(tmp = strstr(tmp, word)){
      printf("%.50s\n", tmp);
      rep++;
      tmp++;
   }

   printf("Word count: %d\n", rep);
   fclose(f);
   system("gedit output.txt");

   return 0;
}

我复制了原始输入,因此我可以保持原样并从中获取“之前”字符。

在 tmp(原始输入副本)上使用 strstr() 我可以找到我正在寻找的单词的实例并打印前 50 个字符。但是知道这一点,我如何才能访问此实例之前的 50 个字符?

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 由于tmp 只是一个指针,tmp-50 将精确指向它之前的 50 个字符。 (请测试它是否仍在您的数据中。)
  • 顺便说一下,目前你没有得到“字符串后面的 50 个字符”,因为这个计数也包括你的搜索字符串。打印前添加strlen(word)tmp
  • 只是检查 - 你看到我的答案了吗?它有帮助吗?如果没有,缺少什么?

标签: c string char strstr


【解决方案1】:

除了打印问题本身之外,您的代码中还有一些错误。我已经纠正了其中的大部分;一个简短的列表是:

  1. 总是测试malloc是否成功。
  2. fread(text, 100, 10000000, ..) 读取的文本太多。 100 * 10000000 = 1000000000,几乎是一个完整的千兆字节。您只为 10 Mb 分配了足够的内存。
  3. 您从文本文件中读取数据并将此数据视为字符串。因此,您必须确保数据以0 结尾,否则printfstrstr 等函数会在结束后尝试继续读取。
  4. 您的 rep 变量开始时未初始化,因此您将始终看到一个随机数。
  5. 始终释放您分配的内存。

也就是说,使用专用函数打印文本的效率稍高一些——如果只是不要在您的 main 中添加太多内容。而且由于它是一个函数,因此您可以根据需要向其中添加任意数量的有用参数;我添加了beforeafter 变量,因此您可以改变显示的字符数。

为了更加美观,当在before 字符的最小数量之前找到短语时,此函数会打印正确数量的空格,因此结果排列得很好。另外,由于打印出诸如制表符和换行符之类的字符会弄乱您的输出,因此我将它们替换为?

诚然,print_range 中有一些重复,但在这种情况下,我是为了清楚,而不是简洁。

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

#define MAX_LENGTH  10000000

void print_range (char *source_text, int startindex, int before, int after, int phrase_length)
{
    int i;

    if (before > startindex)
    {
        for (i=0; i<before-startindex; i++)
            printf (" ");
        startindex = before;
    }

    for (i=0; i<before; i++)
    {
        if (strchr ("\t\r\n", source_text[startindex-before+i]))
            printf ("?");
        else
            printf ("%c", source_text[startindex-before+i]);
    }
    for (i=0; i<phrase_length; i++)
    {
        if (strchr ("\t\r\n", source_text[startindex+i]))
            printf ("?");
        else
            printf ("%c", source_text[startindex+i]);
    }
    for (i=0; i<after; i++)
    {
        if (!source_text[startindex+phrase_length+i])
            break;
        if (strchr ("\t\r\n", source_text[startindex+phrase_length+i]))
            printf ("?");
        else
            printf ("%c", source_text[startindex+phrase_length+i]);
    }
    printf ("\n");
}

int main (int argc, char *argv[]){

    char *text = (char *) malloc (MAX_LENGTH);
    char *word = argv[1];
    int rep = 0;

    if (!text)
        return -1;

    if(argc < 2)
    {
         printf("Usage: GET <website> | ./word_counter <word>\n");
         exit(1);
    }

    fread(text, 1, MAX_LENGTH, stdin);
    text[MAX_LENGTH] = 0;

    const char *tmp = text;

    do
    {
        tmp = strstr(tmp, word);
        if (!tmp)
            break;
        print_range (text, tmp-text, 16,16, strlen(word));
        rep++;
        tmp++;
    } while (1);

    free (text);

    printf ("Word count: %d\n", rep);

    return 0;
}

在自己的源代码上运行的结果:

~/Documents $ ./wordcounter printf < wordcounter.c
tindex; i++)????printf (" ");???starti
-before+i]))????printf ("?");???else??
"?");???else????printf ("%c", source_t
before+i]);??}??printf ("{");??for (i=
rtindex+i]))????printf ("?");???else??
"?");???else????printf ("%c", source_t
tindex+i]);??}??printf ("}");??for (i=
_length+i]))????printf ("?");???else??
"?");???else????printf ("%c", source_t
length+i]);??}??printf ("\n");?}??int 
argc < 2)??{??? printf("Usage: GET <we
?free (text);???printf ("Word count: %
Word count: 12

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2016-02-02
    • 2011-04-02
    相关资源
    最近更新 更多