vuoi
o PayPal
tutte le volte che vuoi
Formattazione del testo con tag HTML
Adesso pensiamo a come fare la condizione per identificare i caratteri minuscoli. Guardando la tabella ASCII notiamo che le maiuscole sono fra la rappresentazione decimale 65 e la 90. Le minuscole invece sono tra 97 e 122. Possiamo quindi sviluppare lo pseudocodice precedente così:
while (...) { if (65 <= array[i] <= 90) { array[i] -= 32; } else if (97 <= array[i] <= 122) { array[i] += 32; } }
Ecco il programma finale:
#include <stdio.h>
#include <assert.h>
#include <string.h>
int main(void) {
char array[100] = "thiS Is a WORD!";
int i = 0;
while (array[i] != '\0') {
if (array[i] >= 97 && array[i] <= 122) {
array[i] -= 32;
} else if (array[i] >= 65 && array[i] <= 90) {
array[i] += 32;
}
i++;
}
printf("%s\n", array);
assert(strcmp(array, "THIs iS A word!") == 0);
return 0;
}
Franco Masotti, 2023 | https://blog.franco.net.eu.org
string.h
strcmp
ci serve per chiamare
- Iteriamo tutta la stringa
- Troviamo le minuscole e facciamo la conversione
- Troviamo le maiuscole e facciamo la conversione
assert
La funzione permette di verificare se il nostro algoritmo funziona. Viene spesso usata in fase di debug. Se quello che si trova dentroassert
è falso il programma termina immediatamente con un errore. La funzione confronta una stringa con un'altra. Se le due stringhe in input sono uguali la funzione ritorna0
. Quindi, usandoassert
assieme astrcmp
possiamo verificare di aver fatto tutto correttamente- Per risolvere questo esercizio è anche possibile utilizzare le funzioni
isupper
,islower
,toupper
,tolower
definite inctype.h
.
NOTE qui sotto, anche se in C++, riporta un'altra soluzione che utilizza queste funzioni.
Approfondimento
Qui sotto trovate la soluzione in C++ usando alcune funzioni integrate. La logica è la stessa della soluzione originaria in C.
C.<iostream> #include <assert.h> int main(void) { std::string array = "thiS Is a WORD!"; int i = 0; while (array[i] != '\0') { if (isupper(array[i])) { array[i] = tolower(array[i]); } else if (islower(array[i])) { array[i] = toupper(array[i]); } i++; } std::cout << array; assert(array.compare("THIs iS A word!") == 0); return 0; } Esercizio 2 Consegna: data una stringa (tipo char *) array, invertirla e salvare il risultato in result. Data una stringa (tipo char *) array, invertirla e salvare il risultato in result. #include <stdio.h> int main(void) { char array[100] = "Questa e' una stringa di prova"; char result[100]; int i = 0; while (array[i] != '\0') { i++; } int j = 0; while (i >= 0) { result[j] = array[i]; i--; j++; } printf("%s\n", result); return 0; }
<stdio.h>
#include <stdlib.h>
int main(void) {
char array[100] = "Questa e' una stringa di prova";
char result[100];
int length = 0;
int i, j = 0;
while (array[length] != '\0') {
length++;
}
length--;
for (i = length; i >= 0; i--, j++) {
result[j] = array[i];
}
result[j] = '\0';
printf("%s\n", result);
return 0;
}
Perché:
- devo sottrarre 1 perché in C gli array partono da 0 '\0',
- devo arrivare all'indice della stringa subito prima del carattere quindi devo sottrarre 1 un'altra volta
Partendo dalla fine della stringa vado verso l'inizio e salvo carattere per carattere:
| Franco Masotti, 2023 | https://blog.franco.net.eu.org |
Aggiungo il carattere terminatore alla fine della stringa risultato.
Soluzione alternativa:
È anche possibile invertire una stringa senza calcolare a priori la lunghezza ma comunque scorrendola normalmente dall'inizio fino alla fine. Quando si è giunti alla fine si scorre al contrario salvando carattere per carattere.
#include <stdio.h> int main(void) { char array[100] = "Questa è una stringa di prova"; char result[100]; char i = 0, j = 0, done = 0, go_back = 0; while (!done) { if (array[i] == '\0') { go_back = 1; i--; } if (go_back) { result[j] = array[i]; j++; i--; } else { done = 1; } } result[j] = '\0'; printf("%s\n", result); return 0; }
- Una volta arrivati in fondo alla stringa, si va indietro di una posizione per saltare il carattere terminatore. Setto anche il flag che dice di spostare l'indice indietro.
- Salvo un carattere per volta nella stringa result.
- Proseguo sulla casella successiva di result array e sulla casella precedente di array.
- Proseguo sulla casella successiva di array perché devo ancora arrivare alla fine della stringa.
- Setto il flag done per uscire dal ciclo. In questo modo si evita di andare in underflow array leggendo la stringa originale.
Esercizio 3
Consegna
Modificare l'esercizio precedente per fare in modo che la stringa venga letta dall'utente all'interno di un ciclo. EOF Quando l'utente inserisce la stringa il programma deve terminare e si deve il programma e'
terminato. Stampare a video strcmp, strlen, ecc...
Non è consentito usare funzioni quali
Potete usare la traccia precedente.
Soluzione
Possiamo estendere la soluzione precedente mettendola all'interno di un ciclo while, così:
while <non viene letto "EOF"> <inverti stringa> "EOF\0"
Per sapere se l'utente ha inserito esattamente si può procedere carattere per carattere. Non sapendo a priori la lunghezza della stringa bisogna controllare di non '\0' raggiungere il carattere terminatore.
Possiamo migliorare lo pseudocodice precedente con questo:
done = false; while (!done) { scanf ... if (array[0] != '\0' && array[0] == 'E' && array[1] != '\0' && array[1] == 'O' && array[2] != '\0' && array[2] == 'F' && array[3] != '\0') done = true; else <inverti stringa> }
E,
8 | Franco Masotti, 2023 | https://blog.franco.net.eu.org
per finire, ecco il codice completo:
<stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(void) {
char array[100];
char result[100];
bool done = false;
int length = 0, i, j;
while (!done) {
length = 0;
done = false;
printf("inserire una stringa da invertire (EOF per uscire, max 99 caratteri): ");
scanf("%s", array);
if (array[0] != '\0' && array[0] == 'E' && array[1] != '\0' && array[1] == 'O' && array[2] != '\0' && array[2] == 'F' && array[3] == '\0') {
done = true;
printf("il programma e' terminato\n");
}
if (!done) {
while (array[length] != '\0') {
length++;
}
length--;
j = 0;
for (i = length; i >= 0; i--, j++) {
result[j] = array[i];
}
result[j] = '\0';
printf("risultato: %s\n", result);
}
}
return 0;
}
Franco Masotti, 2023 | https://blog.franco.net.eu.org | 9viene settato il flag② scanf
Usiamo il classico③ "EOF\0"
Controllo se l’utente ha immesso esattamente④ if
Il codice all’interno dell’ <code> </code> è uguale a quello dell’esercizio precedente.
scanf non c’è nessun controllo di overflow con la stringa!
Usando Infatti inserendo troppi caratteri si incappa in un errore di scanf %s segmentazione. Inoltre la funzione con ignora gli spazi
WARNING scanf non è una funzione
prima e dopo la stringa. In generalesicura ma è comunque adatta per spiegare questi problemiintroduttivi.
Esercizio 4
Consegna
Data una stringa controllare se è palindroma.
Una parola palindroma si legge allo stesso modo da sinistra a destra e da destra a sinistra: per esempio, è una parola palindroma.
Il programma non deve prevedere la gestione dei caratteri whitespace: per esempio onora rono non deve risultare come palindromo.
main true false
La funzione deve ritornare se è palindroma oppure se non lo è.
#include <stdio.h> #include <stdbool.h> int main(void) { // La stringa è di 128 caratteri + 1 carattere terminatore di stringa. char array[129] = "EaQDQeLCUsddXqFOUjFMcFPUxNZzdtuctIIKZzOmDyxHoNDbqtaT" "oBAbWBCoIqDzzDqIoCBWbABoTatqbDNoHxyDmOzZKIItcutdzZNx" "UPFcMFjUOFqXddsUCLeQDQaE"; bool palindrome;