#c #winapi #colors #console
#c #winapi #Цвет #консоль
Вопрос:
По сути, я работаю над этой программой текстового редактора для школьного проекта, которая использует простые функции подачи и строки для создания, добавления, удаления, отображения, дублирования или поиска в текстовых файлах. Мне удалось объединить все функции, и мой вопрос относится к моей Search()
функции, которую я прикреплю в конце этого для справки. Если ключевое слово поиска найдено, функция печатает, в какой строке оно было найдено, и печатает саму строку. Что я хотел бы сделать, это, если возможно, изменить цвет ключевого слова поиска при печати строки, чтобы оно выделялось, и пользователь мог сразу определить, где находится его ключевое слово в строке. Я не спрашиваю об этом, не проводя НИКАКИХ исследований по этому вопросу; Я немного покопался, и, похоже, я могу использовать escape-последовательности ANSI или последовательности виртуальных терминалов консоли Windows для достижения того, что я пытаюсь сделать, и я просмотрел документацию на веб-сайте Microsoft, но, к сожалению, япока мне не нравится вызывать API-интерфейсы Windows, и мне действительно не помешала бы помощь, чтобы выяснить, как именно это сделать. Кроме того, заранее приношу извинения, если код, который я прикрепляю, иногда кажется неэффективным или ненужным, только начал изучать C пару месяцев назад. Я использую компилятор gcc с DevC в Windows 10. TIA.
void Search(void) {
FILE *fptr;
char name[20], key[30], line[100];
int linenum=1, found=0;
printf("Enter name of text file to search from, or enter 'exit' to cancel and return to menu: ");
gets(name);
if(strcmp(name,"exit") == 0)
return;
strcat(name,".txt");
fptr = fopen(name,"r");
while(!fptr) { // just some input validation
printf("Error. Text file not found. Make sure it exists and is placed in the same folder as the .exe file for this program.");
fclose(fptr);
printf("nnEnter name of text file to search from, or enter 'exit' to cancel and return to menu: ");
gets(name);
if(strcmp(name,"exit") == 0)
return;
strcat(name,".txt");
fptr = fopen(name,"r");
}
printf("Enter your search keyword (remember, it is case sensitive): "); //searching staarts here
gets(key);
while(!feof(fptr)) {
fgets(line,100,fptr);
if(strstr(line,key)) {
printf("Keyword found in line %d:n", linenum);
printf("----------------------------------------------------------------------------------------------n");
printf("%s",line);
printf("----------------------------------------------------------------------------------------------nn");
found=1;
}
linenum ;
}
if(!found)
printf("Keyword not found in file.");
printf("nPress any key to return to main menu: ");
getch();
}
Причина, по которой я использовал длинный ———— разделители — это то, что я хочу отличать содержимое текстового файла от содержимого того, что написано в окне консоли.
Комментарии:
1. В зависимости от вашей консоли вы можете использовать экранирующие коды ANSI
2. Также называемые виртуальными последовательностями терминалов .
3. Да, я столкнулся с этим, исследуя, как это сделать, просто я не мог найти достаточно простого ответа относительно того, как на самом деле реализовать их в моем коде. Действительно ценю толчок в правильном направлении.
Ответ №1:
В принципе, вы можете полагаться на string class для выполнения этой задачи, использовать string :: find
для извлечения местоположения ключа, а затем использовать string:: substr
для печати значения ключа.
Обратитесь к приведенному ниже коду:
void Search(void) {
...
printf("Enter your search keyword (remember, it is case sensitive): "); //searching staarts here
gets_s(key);
while (!feof(fptr)) {
fgets(line, 100, fptr);
if (strstr(line, key)) {
std::string str(line);
printf("Keyword found in line %d:n", linenum);
printf("----------------------------------------------------------------------------------------------n");
int pos = str.find(key);
int len = strlen(key);
int len_t = strlen(line);
if (pos != 0)
{
printf("%s", str.substr(0, pos).c_str());
printf("x1b[31m%s", str.substr(pos, len).c_str());
printf("x1b[0m%srn", str.substr(len pos, len_t).c_str());
}
else
{
printf("x1b[31m%s", str.substr(pos, len).c_str());
printf("x1b[0m%srn", str.substr(pos len, len_t).c_str());
}
printf("x1b[0m----------------------------------------------------------------------------------------------nn");
found = 1;
}
linenum ;
}
if (!found)
printf("Keyword not found in file.");
printf("nPress any key to return to main menu: ");
getch();
}
Комментарии:
1. Вау, это потрясающе. Это именно то, на что я надеялся. Большое вам спасибо!
Ответ №2:
В качестве альтернативы вы могли бы просто использовать функции консоли Windows API:
#include <stdio.h>
#include <windows.h>
int main()
{
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hstdout, FOREGROUND_RED|FOREGROUND_INTENSITY);
printf("hello ");
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN|FOREGROUND_INTENSITY);
printf("world");
return 0;
}