Manipolazione di testo, gestione del tempo e interazione con l'utente.
π₯οΈ In pratica con Windows Forms: TextBox e Label per l'input.
Operazioni sulle Stringhe
Le stringhe sono uno dei tipi di dati piΓΉ utilizzati nella programmazione. In C#, le stringhe sono
oggetti immutabili che rappresentano sequenze di caratteri. La classe String
fornisce numerosi metodi per manipolare e trasformare il testo.
Cosa Significa "Immutabile"?
Quando modifichi una stringa in C#, in realtΓ stai creando una nuova stringa in memoria. La stringa originale non viene modificata. Questo Γ¨ importante da capire per ottimizzare le performance quando lavori con molte concatenazioni.
Creazione e Concatenazione
Metodi di Concatenazione
// Creazione di stringhe
string nome = "Mario";
string cognome = "Rossi";
// Concatenazione con l'operatore +
string nomeCompleto = nome + " " + cognome; // "Mario Rossi"
// Concatenazione con il metodo Concat
string nomeCompleto2 = String.Concat(nome, " ", cognome);
// Interpolazione di stringhe (C# 6.0+) - CONSIGLIATO
string saluto = $"Ciao, {nome} {cognome}!"; // "Ciao, Mario Rossi!"
// StringBuilder per concatenazioni multiple (piΓΉ efficiente)
using System.Text;
StringBuilder sb = new StringBuilder();
sb.Append("Ciao, ");
sb.Append(nome);
sb.Append(" ");
sb.Append(cognome);
sb.Append("!");
string risultato = sb.ToString(); // "Ciao, Mario Rossi!"
β‘ Quando Usare StringBuilder?
Usa StringBuilder quando devi fare molte concatenazioni in loop o operazioni ripetute.
Per 2-3 concatenazioni semplici, l'operatore + o l'interpolazione $"" vanno benissimo.
Ricerca e Sostituzione
Metodi di Ricerca
string testo = "La programmazione in C# Γ¨ divertente e potente";
// Ricerca
bool contiene = testo.Contains("C#"); // true
int posizione = testo.IndexOf("divertente"); // 26
bool iniziaCon = testo.StartsWith("La"); // true
bool finisceCon = testo.EndsWith("potente"); // true
// Sostituzione
string nuovo = testo.Replace("C#", "C Sharp");
// "La programmazione in C Sharp Γ¨ divertente e potente"
// Divisione in base a un separatore
string[] parole = testo.Split(' ');
// ["La", "programmazione", "in", "C#", "Γ¨", "divertente", "e", "potente"]
| Metodo | Descrizione | Ritorna |
|---|---|---|
Contains(string) |
Verifica se contiene una sottostringa | bool |
IndexOf(string) |
Trova la posizione di una sottostringa | int (-1 se non trovata) |
Replace(old, new) |
Sostituisce tutte le occorrenze | string (nuova) |
Split(char) |
Divide in array in base a separatore | string[] |
Estrazione e Modifica
Operazioni di Estrazione
string email = "mario.rossi@example.com";
// Estrazione di sottostringhe
string username = email.Substring(0, email.IndexOf('@'));
// "mario.rossi"
string dominio = email.Substring(email.IndexOf('@') + 1);
// "example.com"
// Modifica del caso
string maiuscolo = email.ToUpper();
// "MARIO.ROSSI@EXAMPLE.COM"
string minuscolo = email.ToLower();
// "mario.rossi@example.com"
// Rimozione di spazi
string conSpazi = " testo con spazi ";
string senzaSpazi = conSpazi.Trim(); // "testo con spazi"
string senzaSpaziInizio = conSpazi.TrimStart(); // "testo con spazi "
string senzaSpaziFinale = conSpazi.TrimEnd(); // " testo con spazi"
π Metodi Utili per la Manipolazione
Estrazione
Substring(start, length)Remove(start, count)Insert(index, text)
Modifica
ToUpper() / ToLower()Trim() / TrimStart() / TrimEnd()PadLeft() / PadRight()
Formattazione Stringhe
Formattazione Avanzata
// Utilizzo di String.Format
string formato = String.Format("Nome: {0}, EtΓ : {1}", "Mario", 30);
// "Nome: Mario, EtΓ : 30"
// Formattazione di numeri
double prezzo = 1250.75;
string prezzoFormattato = prezzo.ToString("C"); // "β¬ 1.250,75"
string prezzoFormattato2 = prezzo.ToString("N2"); // "1.250,75"
// Allineamento e padding
string testo = "test";
string allineato = testo.PadLeft(10); // " test"
string allineatoConCarattere = testo.PadRight(10, '-'); // "test------"
| Formato | Descrizione | Esempio |
|---|---|---|
C |
Valuta | β¬ 1.250,75 |
N2 |
Numero con 2 decimali | 1.250,75 |
F1 |
Fixed point con 1 decimale | 1250,8 |
P |
Percentuale | 12,51 % |
Lavorare con le Date (DateTime)
La classe DateTime rappresenta un momento specifico nel tempo, espresso come data e ora.
Offre numerosi metodi per manipolare e formattare date e orari.
Creazione e Accesso
// Data e ora corrente
DateTime now = DateTime.Now;
DateTime today = DateTime.Today; // Solo data, ore a 00:00:00
// Creazione di una data specifica
DateTime compleanno = new DateTime(1990, 5, 15);
DateTime compleannoOra = new DateTime(1990, 5, 15, 14, 30, 0);
// Accesso alle componenti
int anno = now.Year;
int mese = now.Month;
int giorno = now.Day;
int ora = now.Hour;
int minuto = now.Minute;
int secondo = now.Second;
// Giorno della settimana
DayOfWeek giornoSettimana = now.DayOfWeek; // Sunday, Monday, ...
β° ProprietΓ Importanti di DateTime
Data e Ora
DateTime.Now- Data e ora attualiDateTime.Today- Solo data (00:00:00)DateTime.UtcNow- Ora UTC
Componenti
Year, Month, DayHour, Minute, SecondDayOfWeek, DayOfYear
Operazioni con DateTime
Addizione, Sottrazione e Formattazione
// Addizione e sottrazione
DateTime domani = DateTime.Today.AddDays(1);
DateTime treSettimaneFa = DateTime.Today.AddDays(-21);
DateTime unAnnoDopoOggi = DateTime.Today.AddYears(1);
DateTime traUnOra = DateTime.Now.AddHours(1);
// Differenza tra date
TimeSpan differenza = domani - DateTime.Today; // 1 giorno
double giorni = differenza.TotalDays; // 1.0
double ore = differenza.TotalHours; // 24.0
// Formattazione date
DateTime data = new DateTime(2024, 5, 15, 14, 30, 25);
string formato1 = data.ToString("dd/MM/yyyy"); // "15/05/2024"
string formato2 = data.ToString("dd/MM/yyyy HH:mm:ss"); // "15/05/2024 14:30:25"
string formato3 = data.ToString("dddd, d MMMM yyyy"); // "mercoledì, 15 maggio 2024"
string formato4 = data.ToString("HH:mm"); // "14:30"
| Formato | Descrizione | Esempio |
|---|---|---|
dd/MM/yyyy |
Data breve | 15/05/2024 |
dddd, d MMMM yyyy |
Data estesa | mercoledì, 15 maggio 2024 |
HH:mm:ss |
Ora formato 24h | 14:30:25 |
hh:mm tt |
Ora formato 12h | 02:30 PM |
π‘ TimeSpan vs DateTime
TimeSpan rappresenta un intervallo di tempo (durata),
mentre DateTime rappresenta un momento specifico nel tempo.
Usa TimeSpan per calcolare differenze tra date o per rappresentare durate.
Input Utente dalla Console
L'interazione con l'utente Γ¨ fondamentale per molte applicazioni. In un'applicazione console,
utilizziamo la classe Console per ottenere input dall'utente.
Lettura di Input Base
// Lettura di una stringa
Console.Write("Inserisci il tuo nome: ");
string nome = Console.ReadLine();
// Lettura di un numero (con conversione sicura)
Console.Write("Inserisci la tua etΓ : ");
string inputEta = Console.ReadLine();
int eta;
if (int.TryParse(inputEta, out eta))
{
Console.WriteLine($"Tra 10 anni avrai {eta + 10} anni");
}
else
{
Console.WriteLine("Input non valido");
}
// Lettura di un singolo carattere (tasto)
Console.WriteLine("Premi un tasto per continuare...");
char tasto = Console.ReadKey().KeyChar;
β οΈ Metodi di Lettura Console
ReadLine()
- Legge un'intera riga
- Ritorna una stringa
- Attende INVIO
ReadKey()
- Legge un singolo tasto
- Ritorna ConsoleKeyInfo
- Non attende INVIO
Validazione dell'Input
Γ importante validare l'input dell'utente per evitare errori durante l'esecuzione del programma. Ecco alcuni esempi di validazione robusta.
Validazione di un Numero
bool inputValido = false;
int numero = 0;
while (!inputValido)
{
Console.Write("Inserisci un numero tra 1 e 100: ");
string input = Console.ReadLine();
if (int.TryParse(input, out numero))
{
if (numero >= 1 && numero <= 100)
{
inputValido = true;
}
else
{
Console.WriteLine("β Il numero deve essere compreso tra 1 e 100");
}
}
else
{
Console.WriteLine("β Input non valido. Inserisci un numero intero");
}
}
Console.WriteLine($"β
Hai inserito: {numero}");
Validazione di una Data
DateTime dataNascita;
bool dataValida = false;
while (!dataValida)
{
Console.Write("Inserisci la tua data di nascita (gg/mm/aaaa): ");
string input = Console.ReadLine();
if (DateTime.TryParseExact(input, "dd/MM/yyyy", null,
System.Globalization.DateTimeStyles.None,
out dataNascita))
{
if (dataNascita <= DateTime.Today)
{
dataValida = true;
// Calcolo etΓ precisa
int eta = DateTime.Today.Year - dataNascita.Year;
// Controllo se il compleanno Γ¨ giΓ passato quest'anno
if (dataNascita.Month > DateTime.Today.Month ||
(dataNascita.Month == DateTime.Today.Month &&
dataNascita.Day > DateTime.Today.Day))
{
eta--;
}
Console.WriteLine($"β
La tua etΓ Γ¨: {eta} anni");
}
else
{
Console.WriteLine("β La data non puΓ² essere nel futuro");
}
}
else
{
Console.WriteLine("β Formato data non valido. Usa: gg/mm/aaaa");
}
}
π‘οΈ Best Practice per la Validazione
- Usa sempre
TryParseinvece diParseper evitare eccezioni - Fornisci messaggi di errore chiari e specifici
- Usa loop
whileper ripetere la richiesta fino a input valido - Valida sia il formato che il range dei valori
Esempio Pratico: Gestione Appuntamenti
Vediamo un esempio completo che integra stringhe, date e input utente per creare un semplice sistema di gestione appuntamenti.
Program.cs - Sistema Appuntamenti
using System;
using System.Collections.Generic;
class Appuntamento
{
public string Titolo { get; set; }
public DateTime DataOra { get; set; }
public string Descrizione { get; set; }
public override string ToString()
{
return $"{DataOra.ToString("dd/MM/yyyy HH:mm")} - {Titolo}";
}
}
class Program
{
static List<Appuntamento> appuntamenti = new List<Appuntamento>();
static void Main()
{
bool continua = true;
while (continua)
{
Console.WriteLine("\nββββββββββββββββββββββββββββββββββ");
Console.WriteLine("β GESTIONE APPUNTAMENTI β");
Console.WriteLine("ββββββββββββββββββββββββββββββββββ");
Console.WriteLine("1. Aggiungi appuntamento");
Console.WriteLine("2. Visualizza appuntamenti");
Console.WriteLine("3. Cerca appuntamenti per data");
Console.WriteLine("4. Esci");
Console.Write("\nScegli un'opzione: ");
string scelta = Console.ReadLine();
switch (scelta)
{
case "1":
AggiungiAppuntamento();
break;
case "2":
VisualizzaAppuntamenti();
break;
case "3":
CercaAppuntamenti();
break;
case "4":
continua = false;
Console.WriteLine("Arrivederci!");
break;
default:
Console.WriteLine("β Opzione non valida");
break;
}
}
}
static void AggiungiAppuntamento()
{
Appuntamento app = new Appuntamento();
Console.Write("\nTitolo: ");
app.Titolo = Console.ReadLine();
DateTime dataOra;
bool dataValida = false;
while (!dataValida)
{
Console.Write("Data e ora (dd/MM/yyyy HH:mm): ");
string input = Console.ReadLine();
if (DateTime.TryParseExact(input, "dd/MM/yyyy HH:mm", null,
System.Globalization.DateTimeStyles.None,
out dataOra))
{
app.DataOra = dataOra;
dataValida = true;
}
else
{
Console.WriteLine("β Formato non valido. Riprova.");
}
}
Console.Write("Descrizione: ");
app.Descrizione = Console.ReadLine();
appuntamenti.Add(app);
Console.WriteLine("β
Appuntamento aggiunto con successo!");
}
static void VisualizzaAppuntamenti()
{
if (appuntamenti.Count == 0)
{
Console.WriteLine("\nπ Nessun appuntamento presente");
return;
}
Console.WriteLine("\nπ Elenco degli appuntamenti:");
appuntamenti.Sort((a, b) => a.DataOra.CompareTo(b.DataOra));
for (int i = 0; i < appuntamenti.Count; i++)
{
Console.WriteLine($"{i+1}. {appuntamenti[i]}");
if (!string.IsNullOrEmpty(appuntamenti[i].Descrizione))
{
Console.WriteLine($" β {appuntamenti[i].Descrizione}");
}
}
}
static void CercaAppuntamenti()
{
if (appuntamenti.Count == 0)
{
Console.WriteLine("\nπ Nessun appuntamento presente");
return;
}
DateTime dataRicerca;
bool dataValida = false;
while (!dataValida)
{
Console.Write("\nInserisci la data da cercare (dd/MM/yyyy): ");
string input = Console.ReadLine();
if (DateTime.TryParseExact(input, "dd/MM/yyyy", null,
System.Globalization.DateTimeStyles.None,
out dataRicerca))
{
dataValida = true;
Console.WriteLine($"\nπ
Appuntamenti del {dataRicerca.ToString("dd/MM/yyyy")}:");
bool trovato = false;
foreach (var app in appuntamenti)
{
if (app.DataOra.Date == dataRicerca.Date)
{
Console.WriteLine($"β’ {app.DataOra.ToString("HH:mm")} - {app.Titolo}");
if (!string.IsNullOrEmpty(app.Descrizione))
{
Console.WriteLine($" β {app.Descrizione}");
}
trovato = true;
}
}
if (!trovato)
{
Console.WriteLine("π Nessun appuntamento per questa data");
}
}
else
{
Console.WriteLine("β Formato data non valido. Usa: dd/MM/yyyy");
}
}
}
}
π‘ FunzionalitΓ del Programma
- Aggiunta: Crea nuovi appuntamenti con validazione dell'input
- Visualizzazione: Mostra tutti gli appuntamenti ordinati per data
- Ricerca: Trova appuntamenti per una data specifica
- Validazione: Controlla formato date e gestisce errori
Esercizi Pratici
Esercizio 1: Analizzatore di Email
Crea un programma che chiede all'utente di inserire un indirizzo email e poi:
- Estrae e visualizza il nome utente (parte prima della @)
- Estrae e visualizza il dominio (parte dopo la @)
- Verifica se l'email contiene un punto nel dominio
- Converte l'email in maiuscolo e minuscolo
Mostra la soluzione
Soluzione Esercizio 1
using System;
class Program
{
static void Main()
{
Console.Write("Inserisci un indirizzo email: ");
string email = Console.ReadLine();
// Verifica che contenga @
if (!email.Contains("@"))
{
Console.WriteLine("β Email non valida: manca @");
return;
}
// Estrazione username e dominio
int posChiocciola = email.IndexOf('@');
string username = email.Substring(0, posChiocciola);
string dominio = email.Substring(posChiocciola + 1);
// Output informazioni
Console.WriteLine("\n=== ANALISI EMAIL ===");
Console.WriteLine($"Email completa: {email}");
Console.WriteLine($"Username: {username}");
Console.WriteLine($"Dominio: {dominio}");
// Verifica punto nel dominio
if (dominio.Contains("."))
{
Console.WriteLine("β
Il dominio contiene un punto");
}
else
{
Console.WriteLine("β οΈ Il dominio non contiene un punto");
}
// Conversioni
Console.WriteLine($"\nMaiuscolo: {email.ToUpper()}");
Console.WriteLine($"Minuscolo: {email.ToLower()}");
}
}
Esercizio 2: Calcolatore di EtΓ
Crea un programma che:
- Chiede all'utente la data di nascita (formato dd/MM/yyyy)
- Calcola l'etΓ esatta in anni, mesi e giorni
- Mostra quanti giorni mancano al prossimo compleanno
- Indica il giorno della settimana in cui Γ¨ nato l'utente
Mostra la soluzione
Soluzione Esercizio 2
using System;
class Program
{
static void Main()
{
DateTime dataNascita;
bool dataValida = false;
// Input con validazione
while (!dataValida)
{
Console.Write("Inserisci la data di nascita (dd/MM/yyyy): ");
string input = Console.ReadLine();
if (DateTime.TryParseExact(input, "dd/MM/yyyy", null,
System.Globalization.DateTimeStyles.None,
out dataNascita))
{
if (dataNascita <= DateTime.Today)
{
dataValida = true;
}
else
{
Console.WriteLine("β La data non puΓ² essere nel futuro");
}
}
else
{
Console.WriteLine("β Formato non valido. Usa: dd/MM/yyyy");
}
}
// Calcolo etΓ
DateTime oggi = DateTime.Today;
int anni = oggi.Year - dataNascita.Year;
// Aggiusta se il compleanno non Γ¨ ancora passato quest'anno
DateTime compleannoQuestAnno = new DateTime(oggi.Year,
dataNascita.Month,
dataNascita.Day);
if (compleannoQuestAnno > oggi)
{
anni--;
}
// Calcolo giorni al prossimo compleanno
DateTime prossimoCompleanno = compleannoQuestAnno > oggi
? compleannoQuestAnno
: compleannoQuestAnno.AddYears(1);
int giorniAlCompleanno = (prossimoCompleanno - oggi).Days;
// Output
Console.WriteLine("\n=== INFORMAZIONI ===");
Console.WriteLine($"Data di nascita: {dataNascita.ToString("dddd, dd MMMM yyyy")}");
Console.WriteLine($"Sei nato/a di: {dataNascita.ToString("dddd")}");
Console.WriteLine($"EtΓ : {anni} anni");
Console.WriteLine($"Giorni al prossimo compleanno: {giorniAlCompleanno}");
if (giorniAlCompleanno == 0)
{
Console.WriteLine("π Buon compleanno!");
}
}
}
Esercizio 3: Formattatore di Testo
Crea un programma che chiede all'utente di inserire un testo e poi offre un menu per:
- Convertire tutto in maiuscolo
- Convertire tutto in minuscolo
- Invertire maiuscole/minuscole
- Contare parole e caratteri
- Rimuovere spazi iniziali e finali
Mostra la soluzione
Soluzione Esercizio 3
using System;
class Program
{
static void Main()
{
Console.Write("Inserisci un testo: ");
string testo = Console.ReadLine();
bool continua = true;
while (continua)
{
Console.WriteLine("\nβββββββββββββββββββββββββββββ");
Console.WriteLine("β FORMATTATORE DI TESTO β");
Console.WriteLine("βββββββββββββββββββββββββββββ");
Console.WriteLine("1. MAIUSCOLO");
Console.WriteLine("2. minuscolo");
Console.WriteLine("3. Inverti Maiuscole/minuscole");
Console.WriteLine("4. Conta parole e caratteri");
Console.WriteLine("5. Rimuovi spazi");
Console.WriteLine("6. Inserisci nuovo testo");
Console.WriteLine("7. Esci");
Console.Write("\nScegli: ");
string scelta = Console.ReadLine();
switch (scelta)
{
case "1":
Console.WriteLine($"\nβ {testo.ToUpper()}");
break;
case "2":
Console.WriteLine($"\nβ {testo.ToLower()}");
break;
case "3":
string invertito = "";
foreach (char c in testo)
{
if (char.IsUpper(c))
invertito += char.ToLower(c);
else if (char.IsLower(c))
invertito += char.ToUpper(c);
else
invertito += c;
}
Console.WriteLine($"\nβ {invertito}");
break;
case "4":
int caratteri = testo.Length;
string[] parole = testo.Split(new char[] {' ', '\t'},
StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine($"\nβ Caratteri: {caratteri}");
Console.WriteLine($"β Parole: {parole.Length}");
break;
case "5":
Console.WriteLine($"\nβ '{testo.Trim()}'");
break;
case "6":
Console.Write("\nInserisci nuovo testo: ");
testo = Console.ReadLine();
break;
case "7":
continua = false;
break;
default:
Console.WriteLine("β Opzione non valida");
break;
}
}
}
}
π― Riepilogo Lezione
Hai imparato:
- Manipolazione stringhe
- Gestione date con DateTime
- Input utente e validazione
- Formattazione avanzata
Concetti chiave:
- Stringhe sono immutabili
- TryParse per conversioni sicure
- TimeSpan per intervalli
- Sempre validare l'input