scheduler : utilities.c - Owanesh/unifi-eos GitHub Wiki

Modulo di funzioni di generico utilizzo, facilmente adattabili ad altri contesti.

/*
 * Acquisisce una linea di testo da stdin verificando che non sia:
 * TOO_LONG = la stringa è troppo lunga
 * INVALID = la stringa inizia con ' ' or '\n'
 * NO_INPUT = errore di I/O
 */
int getLine(char *buff, size_t sz) {
	int ch, extra;

	if (fgets(buff, sz, stdin) == NULL)
		return NO_INPUT;
	if (buff[0] == ' ' || buff[0] == '\n')
		return INVALID;
	// se la stringa fosse troppo lunga non ci sarebbe carattere di newline
	// è necessario rimuovere le digitazioni presente nel buffer input
	// per non influenzare le prossime richieste
	if (buff[strlen(buff) - 1] != '\n') {
		extra = 0;
		while (((ch = getchar()) != '\n') && (ch != EOF))
			extra = 1;
		return (extra == 1) ? TOO_LONG : OK;
	}

	// rimozione del carattere newline
	buff[strlen(buff) - 1] = '\0';
	return OK;
}

Attraverso l’istruzione fgets() si acquisisce una linea di testo da stdin, che termina con l’invio dell’utente. Se l’utente digita più caratteri di quelli consentiti, viene restituito un messaggio di errore, inoltre il buffer viene ripulito fino all’ultimo carattere digitato (\n o EOF).

/*
 * Consente di selezionare un'opzione specificata nel range di optionsAllowed.
 * allowed[2]-> allowed[0]=min value / allowed[1]=max value
 * disabled[]-> opzioni non valide
 * dis_length-> cardinalità dell'insieme dei valori disabilitati
 * Restituisce il valore valido digitato dall'utente.
 */
int selectOption(char *prompt, int allowed[2], int disabled[],											int dis_length) {
	int value;
	bool valid = false;
	while (!valid) {
		if (prompt != NULL) {
			printf("%s", prompt);
		}
		value = readValue();
		if (!isValueAllowed(value, allowed, disabled, dis_length)) {
			printf("Il valore inserito non risulta nelle opzioni. 											   Riprovare\n");
		} else {
			valid = true;
		}
	}
	return value;
}
/* readValue(): restituisce il valore inserito da stind
 Consente:
 - spazi iniziali : " 123"
 - spazi finali : "123 "
 - zeri iniziali : "00000123"
 Controlla i seguenti errori:
 - No input : ""
 - testo prima di un numero : "abc 123"
 - caratteri speciali : "--123"
 */
int readValue() {
	int value;
	int validSyntax;
	char buffer[100];
	do {
		if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
			//errore di lettura, uscita forzata
			return false;
		}
		char* bufferTrimmed = trim(buffer);
		//trim restituisce NULL se l'utente ha digitato solo "{' ‘}\n"
		if (bufferTrimmed != NULL) {
			// una carattere iniziale resituirebbe 0
			validSyntax = sscanf(bufferTrimmed, "%d", &value)
					&& bufferTrimmed[0] != '\n' && bufferTrimmed[0] != ' ';
		}		if (validSyntax != 1)
			printf("Input sintatticamente non valido. Riprovare: ");
	} while (!validSyntax);
	return value;
}
char *trim(char *str) {
	char *end;
	// Trim spazi iniziali
	while (isspace((unsigned char) *str))
		str++;
	if (*str == '\0' || *str == '\n')  // tutti spazi
		return NULL;
	// Trim spazi finali
	end = str + strlen(str) - 1;
	while (end > str && isspace((unsigned char) *end))
		end--;
	// terminatore aggiornato per ignorare gli eventuali spazi
	*(end + 1) = '\0';

	return str;
}

L’istruzione sscanf() consente in maniera semplice di determinare se il primo carattere inserito è una lettera invece che un numero, restituendo il numero di variabile individuate in base al campo <format> ovvero %d.

/*
 * Controlla che 'num' sia compreso nel range e che sia diverso da un    *	valore disabilitato.
 * Se alloweRange == NULL allora ogni valore è valido (a meno di valori *disabilitati).
 * Restituisce true se il valore digitato è valido, altrimenti false.
 */
bool isValueAllowed(int num, int allowedRange[2], int disabled[],
		int disabled_length) {
	bool valid = true;
	//se allowedRange==NULL oppure num è compreso nel range return true
	bool inRange =(allowedRange == NULL) || 
		(num >= allowedRange[0] && num <= allowedRange[1]) ? true : false;
	int i = 0;
	for (; (i < disabled_length) && valid && inRange; i++) {
		if (num == disabled[i])
			valid = false;
	}
	return valid && inRange;
}

Una tipica richiesta di selezione di un’opzione del menù prevede di richiamare selectOption(), che delega a readValue() di ricevere il valore digitato di verificarne la corretta sintassi (no lettere, no spazi ecc); a sua volta isValueAllowed ne controlla la semantica, cioè che sia compreso nei valori desiderati.

Altre funzioni di pura stampa non vengono riportate perché banali (esempio printMenu(), printRow() ecc comprendono solo printf() adeguatamente formattate).

⚠️ **GitHub.com Fallback** ⚠️