Помимо самого вопроса о печати, в вашем коде есть пара ошибок.Я исправил большинство из них;краткий список:
- Всегда проверка, если
malloc
выполнен успешно. fread(text, 100, 10000000, ..)
читает слишком много текста.100 * 10000000 = 1000000000
, почти полный гигабайт.Вы выделили достаточно памяти только для 10 Мб. - Вы читаете из текстового файла и обрабатываете эти данные как строку.Следовательно, вы должны убедиться, что данные заканчиваются на
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