Открыть сразу несколько окон консоли - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Нужно, чтобы программа запускалась, и открывала 2 окна консоли, в одном выводила "Hello, world", а в другом "Hello, user". Как такое организовать?

Решение задачи: «Открыть сразу несколько окон консоли»

textual
Листинг программы
#include <windows.h>
#include <string.h>
#include <stdio.h>
#define MAX_BUF     256
#define MAX_CONSOLE 2
static char*     ptr_to_str(DWORD_PTR p, char* s);
static DWORD_PTR str_to_ptr(const char* s, int* e);
 
struct pipe {
    HANDLE hin;
    HANDLE hout;
};
BOOL  pipe_connect(pipe* p, char* app);
void  pipe_close(pipe* p);
BOOL  pipe_write(const pipe* p, const char* s, DWORD n);
 
int main(void){
    static struct pipe pipes[MAX_CONSOLE];
    int    i, k;
    char   s[MAX_BUF];
    DWORD  n;
 
    //путь к клиенту
    char path[MAX_PATH] = "client.exe";
 
    //запуск консолей
    for(i = 0; i < MAX_CONSOLE; ++i){
        if(! pipe_connect(&pipes[i], path)){
            fprintf(stderr, "error pipes[%d], pipe_connect\n", i);
            return 1;
        }
    }
    puts("\t\t\t\1\1\1 RUN SERVER");
 
    //по переменке отправлять сообщение двум консолям
    k = 0;
    while(1){
        printf("enter msg: ");
        scanf("%255[^\n]", s);
        fflush(stdin);
 
        n = strlen(s) + 1;
        if(n > 1){
            //выход команда exit
            if(! strcmp(s, "exit")){
                for(i = 0; i < MAX_CONSOLE; ++i)
                    pipe_write(&pipes[i], s, n);
                break;
            }
 
            //отправка k-консоле сообщение
            if(! pipe_write(&pipes[k], s, n))
                printf("error console[%d], pipe_write\n", k);
        }
        k ^= 1;
    }
 
    for(i = 0; i < MAX_CONSOLE; ++i)
        pipe_close(&pipes[i]);
    return 0;
}
 
//установка связи с клиентом
BOOL pipe_connect(pipe* p, char* app){
    char path[MAX_PATH + 1], s[32];
    SECURITY_ATTRIBUTES attr;
    PROCESS_INFORMATION pi; 
    STARTUPINFOA        si;
 
    attr.nLength              = sizeof(attr);
    attr.bInheritHandle       = TRUE;
    attr.lpSecurityDescriptor = NULL;
    if(! CreatePipe(&p->hin, &p->hout, &attr, MAX_BUF + 1))
        return FALSE;
 
    sprintf(path, "%s %s", app, ptr_to_str((DWORD_PTR)p->hin, s));
    memset(&pi, 0, sizeof(pi));
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
 
    if(! CreateProcessA(NULL, path, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
        return FALSE;
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);   
    return TRUE;
}
 
//запись
BOOL pipe_write(const pipe* p, const char* s, DWORD n){
    DWORD w = 0;
    BOOL  r = WriteFile(p->hout, s, n, &w, NULL);
    return (r && (w == n));
}
 
//закрытие
void pipe_close(pipe* p){
    if(p->hout != NULL)
        CloseHandle(p->hout);
    if(p->hin != NULL)
        CloseHandle(p->hin);
    p->hout = p->hin = NULL;
}
 
//преобразование целого числа в строку
static char* ptr_to_str(DWORD_PTR p, char* s){
    char  ds[32];
    int   j, i = 0;
    char*    t = s;
    do {
        ds[i++] = (char)(p % 10) + '0';
    } while((p /= 10) != 0);
 
    for(j = i - 1; j >= 0; --j)
        *s++ = ds[j];
    *s = '\0';
    return t;
}

Объяснение кода листинга программы

  1. Переменные:
    • path (путь к клиенту)
    • s (строка для чтения пользовательского ввода)
    • n (длина строки для чтения пользовательского ввода)
    • k (переменная для выбора консоли для отправки сообщения)
    • i (переменная для перебора консолей)
    • ptr_to_str (статическая функция для преобразования целого числа в строку)
    • pipe_connect (функция для установки связи с клиентом)
    • pipe_write (функция для записи в консоль клиента)
    • pipe_close (функция для закрытия соединения с клиентом)
    • main (главная функция программы)
  2. Функция main выполняет следующие действия:
    • Создает две переменные типа struct pipe для подключения к двум консолям
    • Запускает две консоли с помощью функции pipe_connect
    • Выводит сообщение RUN SERVER после запуска двух консолей
    • В цикле запрашивает у пользователя ввод строки и отправляет её в выбранную консоль
    • Закрывает все соединения с помощью функции pipe_close
  3. Функция pipe_connect выполняет следующие действия:
    • Создает два дескриптора файла для чтения и записи из/в консоль клиента
    • Создает процесс для запуска клиента с помощью функции CreateProcessA
    • Закрывает дескрипторы файлов, связанные с процессом клиента
    • Возвращает TRUE, если процесс клиента успешно запущен
  4. Функция pipe_write выполняет следующие действия:
    • Использует функцию WriteFile для записи строки в консоль клиента
    • Возвращает TRUE, если запись прошла успешно и количество записанных байт соответствует указанному значению
  5. Функция ptr_to_str выполняет следующие действия:
    • Преобразует целое число в строку, используя алгоритм деления на 10 и остатка от деления
    • Возвращает указатель на начало строки
  6. Функция pipe_close выполняет следующие действия:
    • Закрывает оба дескриптора файла, связанных с выбранной консолью
    • Устанавливает оба указателя на NULL
  7. В цикле главного функционала программы пользователю предлагается ввести строку для отправки в выбранную консоль. Если введенная строка равна exit, программа завершается. Если введенная строка не равна exit, программа выбирает следующую консоль для отправки сообщения.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 4.25 из 5