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

Como começar:

#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;
}
Tags : , , ,