Tag: SO2 – 2021 – Ficha 1 v.2.7.pdf
sessão 1 – Trabalhar com caracteres UNICODE na consola, Criar processos utilizando a Windows API e esperar pelo seu término.
Bibliografia de apoio:
Capítulos 2 e 6 do Livro Windows System Programming (da Bibliografia) (pgs. 34-37, 181-187, 192-195)
MSDN: Strings & Unicode e Processes
#include <stdio.h> int main() { printf("Até amanhã\n"); getchar(); return 0; }
ou Use Unicdoe Character Set
ou Use Multi-Byte Character Set
apesar de estar em Use Unicdoe Character Set não é suficiente para escrever os caracteres especiais, vai ser necessário
#include <stdio.h> #include <windows.h> #include <tchar.h> #include <stdlib.h> #include <time.h> #include <fcntl.h> #include <io.h> #define MAX 256 int _tmain(int argc, TCHAR* argv[]) { //argc -> numero de argumentos //argv -> argumentos ////TCHAR vou aceitar argumentos com caracteres especiais TCHAR result[MAX] = TEXT("Olá! Este programa ainda não representa UNICODE\n"); #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); //#include <fcntl.h> #include <io.h> _setmode(_fileno(stdout), _O_WTEXT); //#include <fcntl.h> #include <io.h> _setmode(_fileno(stderr), _O_WTEXT); //#include <fcntl.h> #include <io.h> #endif _tprintf(TEXT("Frase:%s Tamanho:%d (caractares) %d (bytes)\n"), result, _tcslen(result), _tcslen(result) * sizeof(TCHAR)); //mas se fossem funções que não trabalhem com caracteres não é necessário srand(time(NULL)); int aleatorio = rand(); _gettchar(); return 0; } //manipulação de strings: //char -> 1 bytes (caracteres que estão na tabela ASCII) //a alternativa é usar o -> wchar (tem o dobro da capacidade, 2 bytes) e já permite armazenar caracteres UNICODE //ao invés de ter duas versões do progrma, apenas uso uma versão do código //TCHAR, não é um tipo nativo //#include <windows.h> //#include <tchar.h> //e desta forma não vou ter que fazer duas versões do programa: para sistemas mais antigos e mais modernos //_tmain -> main ou wamin //uma string fixa, cada letra ocupa 2 bytes -> L"Olá! Este programa ainda não representa UNICODE\n" //ou uso a macro TEXT("") ou _T("") -> "" para resolver as strings fixas //e vou usar também o _tprintf -> printf ou wprintf //_tcslen -> strlen //_gettchar -> getchar() //preparar a consola para mostrar caracteres wide: // _setmode(stdin, constante); // _setmode(stdout, constante); //calcular o tamanho real: // _tcslen(result)*sizeof(TCHAR) // não interessa se está ou não em unicode
#include <windows.h> #include <tchar.h> #include <fcntl.h> #include <io.h> #include <stdio.h> #define MAX 256 //LPTSTR -> TCHAR * //LPCTSTR -> const THACAR * int _tmain(int argc, LPTSTR argv[]) { TCHAR str[MAX], result[MAX] = TEXT("Olá! Este programa é para aceitar UNICODE. Insira \'fim\' para sair\n"); unsigned int i; //UNICODE: Por defeito, a consola Windows não processa caracteres wide. //A maneira mais fácil para ter esta funcionalidade é chamar _setmode: #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); _setmode(_fileno(stdout), _O_WTEXT); #endif do { _tprintf(result); fflush(stdin); _fgetts(str, MAX, stdin); //fgets msdn -> _fgetts //Retirar \n str[_tcslen(str) - 1] = '\0'; //Maiúsculas for (i = 0; i < _tcslen(str); i++) str[i] = _totupper(str[i]); _stprintf_s(result, MAX, TEXT("Frase:%s, Tamanho:%d\n"), str, _tcslen(str)); } while (_tcsicmp(TEXT("FIM"), str)); return 0; } //setlocale -> para lidar com os caracteres especiais em maiúsculas
Os processos em Windows (child processes) CreateProcess (em linux era fork)
#include <windows.h> #include <tchar.h> #include <fcntl.h> #include <io.h> #include <stdio.h> #define MAX 256 int _tmain(int argc, LPTSTR argv[]) { TCHAR str[MAX], result[MAX] = TEXT("Olá! Este programa é para aceitar UNICODE. Insira \'fim\' para sair\n"); unsigned int i; #ifdef UNICODE _setmode(_fileno(stdin), _O_WTEXT); _setmode(_fileno(stdout), _O_WTEXT); #endif do { _tprintf(result); fflush(stdin); _fgetts(str, MAX, stdin); //fgets msdn -> _fgetts //Retirar \n str[_tcslen(str) - 1] = '\0'; //Maiúsculas for (i = 0; i < _tcslen(str); i++) str[i] = _totupper(str[i]); _stprintf_s(result, MAX, TEXT("Frase:%s, Tamanho:%d\n"), str, _tcslen(str)); } while (_tcsicmp(TEXT("FIM"), str)); TCHAR texto[256] = TEXT("notepad"); STARTUPINFO si; // PROCESS_INFORMATION pi; // //memset(); ZeroMemory(&si, sizeof(si)); // mesmo que o memset mas com tudo a zero ZeroMemory(&pi, sizeof(pi)); // resultado da função: pid do processo, pid da threat principal do processo, //e handle (ponteiro para estrutura) do processo, e handle para a thread principal //pid unico no sistema para cada processo, o handle podem ser vários, cada um com determinada permissão por exemplo si.cb = sizeof(STARTUPINFO); //tamanho da estrutura tem que estar preenchido, pelo menos esse!! .cb //criar um processo -> correr um programa que já foi compilado if (CreateProcess(NULL, // No module name (use command line): se fosse o proprio -> argv[0] ou GetModuleFileName //argv[1], // Command line texto, NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi) // Pointer to PROCESS_INFORMATION structure ) { _tprintf(TEXT("processo foi lançado PID: %d THREAD: %d"), pi.dwProcessId, pi.dwThreadId ); }else { _tprintf("CreateProcess failed (%d).\n", GetLastError()); return; } //esperar pelo processo terminar em linux: wait WaitForSingleObject(pi.hProcess, INFINITE); //ms >0 ou então quando terminar INFINITE //se for 0 só para consulta return 0; }