我需要能够提取子字符串之前和之后的字符,目前我有以下代码:
#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 个字符?
任何帮助将不胜感激。谢谢!
最佳答案
除了打印问题本身之外,您的代码中还存在一些错误。我已经纠正了其中大部分;一个简短的列表是:
- 始终测试
malloc
是否成功。 fread(text, 100, 10000000, ..)
读取了太多文本。100 * 10000000 = 1000000000
,几乎是一千兆字节。您只分配了 10 Mb 的足够内存。- 您从文本文件中读取数据并将其视为字符串。因此,您必须确保数据以
0
结尾,否则printf
和strstr
等函数将尝试在结束后继续读取。 - 您的
rep
变量一开始未初始化,因此您将始终看到一个随机数。 - 始终释放您分配的内存。
也就是说,使用专用函数来打印文本会稍微更有效 - 如果只是为了不在 main
中放置太多内容。由于它是一个函数,因此您可以根据需要向其中添加任意数量的有用参数;我添加了 before
和 after
变量,以便您可以改变显示的字符数。
为了增加美观性,当在最小数量的 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
关于c - C中获取strstr之前和之后的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53561392/