Cpp Tips
From Aino Wiki
Test script C++ on-line con aiuto dell'AI: onecompiler.com
I/O
Scrivere in output
cou rappresenta il video. Sullo standard output:#include <iostream> using namespace std; std::cout << "Ciao mondo" << std::endl; //Comporre una stringa con variabili: int a[7]; std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl; //Oppure: cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << " ";
Supponendo di non usare cou ma un'altra comoda funzione solitamente usata per l'output printf, sarà necessario includere la libreria standard "" (o come in questo caso va bene anche la "")
L'output a schermo è così prodotto in base al tipo di variabile di cui stampare il contenuto. Nel testo primo parametro di printf si può far riferimento a più di una sola variabile, l'importante è che sia indicata nel giusto ordine dopo la prima virgola separatrice dei parametri forniti.
#include <iostream> using namespace std; //Per stampare l'output di un numero: int i = 12; printf("Contatore = %d", i); //Per stampare l'output di un carattere: char carattere = 'x'; printf("Carattere = %c", carattere); //Per stampare l'output di un vettore di caratteri: char testo[] = "Il suono del silenzio"; printf("Testo = %s", testo); //Per stampare l'output di un numero float: float risultato = 10.1 / 2.2; printf("Risultato = %f", risultato); // ancora float risultato = (float)10 / (float)2; printf("Risultato = %f", risultato); //Per stampare l'output di una variabile booleana: bool vero = false; printf("Risultato = %d", vero); //Stamperà 0 printf("Risultato = %d", !vero); //Stamperà 1 // ---- Speciale numeri decimali e formattazione ---- double numero_grande = 123456789.123; double numero_piccolo = 0.000000123; float numero_float = 987.65f; // Stampa il numero grande in notazione esponenziale standard printf("Numero grande (standard): %e\n", numero_grande); // Output: 1.234568e+008 // Stampa il numero piccolo in notazione esponenziale standard printf("Numero piccolo (standard): %e\n", numero_piccolo); // Output: 1.230000e-007 // Stampa il numero grande con 2 cifre decimali printf("Numero grande (2 decimali): %.2e\n", numero_grande); // Output: 1.23e+008 // Stampa il numero float con 3 cifre decimali printf("Numero float (3 decimali): %.3e\n", numero_float); // Output: 9.877e+002 // Uso di %le per double per specificare la precisione printf("Numero double (4 decimali): %.4le\n", numero_grande); // Output: 1.2346e+008
Per andare accapo si usa il carattere speciale \n
Per la corretta rappresentazione delle variabili con printf segue tabella specificatore di formato:
| Codice | Tipo variabile | Esempio |
|---|---|---|
| %d | numero intero | int i = 11; printf("Contatore = %d", i); |
| %d | booleano | bool vero = false; printf("Risultato = %d", vero); //Stamperà 0 printf("Risultato = %d", !vero); //Stamperà 1 |
| %f | numero floating point / double | float risultato = 10.1 / 2.2; printf("Risultato = %f", risultato); |
| %e | numero decimale, in notazione esponenziale | double numero_exp = 123456789.123 printf("Numero esponenziale %e\n", numero_exp); // Output: 1.234568e+008 |
| %c | carattere | char carattere = 'x'; printf("Carattere = %c", carattere); |
| %s | testo\stringa | char testo[] = "Il suono del silenzio"; printf("Testo = %s", testo); |
| %p | puntatore | char str[20] = "Salve mondo."; char* p1; p1 = str; printf("%do elemento: p1=%p il cui contenuto e' %c ovvero %c\n", 1, (void*)p1, *p1, str[0]); |
Acquisire in input
cin rappresenta la tastiera, classe disponibile dalla libreria standard .
Legge caratteri scritti da tastiera sino ad incontrare uno spazio\TAB\NewLine (il motivo è che vengono interpretati da >> come caratteri di fine stringa).cin >> variabile
int mark[5] = {19, 10, 8, 17, 9} // Ottenere un input dall'utente ed immagazzinarlo nel 3° elemento dell'array: cin >> mark[2];
Per attendere la pressione di INVIO: std::cin.get();
std::cout << "\n\nPremi INVIO per terminare..."; std::cin.get();
cin.get()
Utilizzato per l'accesso ad array di caratteri in input include anche gli spazi vuoti (NOTA è l'operatore >> che sostanzialmente li esclude). Acquisisce caratteri sino alla pressione del tasto INVIO.
Sintassi:
-
cin.get(); -
cin.get(array_name, array_size);
#include <iostream> using namespace std; int main() { char name[25]; cin.get(name, 25); cout << name; return 0; }
cin + getline()
Si introdcono getline() e cin.getline():
- getline(cin, string) lavora con
std::stringe automaticamente adegua la lunghezza della stringa destinazione. - cin.getline(char array[], size) lavora con array di caratterie richiede la definizione di una lunghezza definita per il buffer.
getline(cin, variabile)
Per acquisire una frase quindi caratteri da tastiera compresi lo spazio si usa:cin.getline()#include <iostream> using namespace std; int main() { string fullInput; // Using getline() to read a full line of input, including spaces cout << "Enter a full sentence: "; getline(cin, fullInput); // Reads the entire line cout << "You entered: " << fullInput << endl; return 0; }
cin.getline()
E' un'altra versione di getline() ma con una caratteristica aggiuntiva, consente di indicare il massimo numero di caratteri leggibili, tutto quello che eccede varrà troncato. NOTA, ogni carattere eccedente comunque rimarrà nell'input buffer per uso futuro...
#include <iostream> using namespace std; int main() { char greeting[50]; // Buffer size // Using cin.getline() to read up to 50 characters cout << "Enter a greeting: "; cin.getline(greeting, 50); cout << "You entered: " << greeting << endl; return 0; }
Esempio di menu con scelta utente':
#include <iostream> void main() { char arrBufferIn[2]; //Si devono prevedere 2 caratteri: il dato + il terminatore di stringa !!! char userInput = ' '; int len = 0; while ((userInput != '0')) { //Varie operazioni... std::cout << "Digitare 0=(Uscita) o qualsiasi carattere per rieseguire." << std::endl; cin.getline(arrBufferIn, 2); len = (int)strlen(arrBufferIn); //strlen NON conterà il terminatore di stringa '\0' !!! if (len == 1) { userInput = arrBufferIn[0]; } } }
NOTA è da preferire getline() a get() per evitare problemi con il buffer in input con conseguente gestione per evitare acqusizione di caratteri non voluti.
Esempio Acquisizione array di numeri
Esempio reale, estrapolato da una applicazione console in cui si chiede all'utente di inserire da tastiera una sequenza di numeri entro un range (questi numeri sono indici di un array da selezionare).
- La sequenza in input si inserisce in una sola riga e si conclude con la pressione di INVIO.
- La funzione "AskUser_ArraySelectedIndex()" elimina i numeri duplicati;
- esegue l'ordinamento dell'array in uscita.
AskUser_ArraySelectedIndex() restituisce un puntatore ad un array, la variabile int* pntArrSelected.#include <iostream> using namespace std; /// <summary> /// Chide all'utente una sequenza separata da spazi degli indici associati ad un array di dimensione dbSize. /// </summary> /// <param name="dbSize">Valore max dimensione dell'array in output tramite puntatore.</param> /// <returns>Array delle selezioni fatte dall'utente tramite tastiera (la max dimensione è dbSize)</returns> int* AskUser_ArraySelectedIndex(const int dbSize) { cout << "\nInserisci indici da copiare (es. 0 2 4, oppure 1-3). INVIO senza testo seleziona tutto:\n> "; // read line into C buffer char arrBufferIn[c_IN_BUFFER_SIZE]; // Use getline member to read the whole line into the buffer cin.getline(arrBufferIn, c_IN_BUFFER_SIZE); int len = (int)strlen(arrBufferIn); // temporary container for selected indices: dbSize is small, so static array is fine int* pntArrSelected = new int[dbSize]; int selCount = 0; // if empty line -> select all if (len == 0) { for (int i = 0; i < dbSize; ++i) pntArrSelected[selCount++] = i; } else { int p = 0; while (p < len) { // skip separators: spaces, tabs, commas, semicolons while (p < len && (arrBufferIn[p] == ' ' || arrBufferIn[p] == '\t' || arrBufferIn[p] == ',' || arrBufferIn[p] == ';')) ++p; if (p >= len) break; // parse first number (non-negative) if (arrBufferIn[p] < '0' || arrBufferIn[p] > '9') { // invalid starting char, skip it ++p; continue; } int num1 = 0; while (p < len && arrBufferIn[p] >= '0' && arrBufferIn[p] <= '9') { num1 = num1 * 10 + (arrBufferIn[p] - '0'); ++p; } // skip spaces int q = p; while (q < len && (arrBufferIn[q] == ' ' || arrBufferIn[q] == '\t')) ++q; if (q < len && arrBufferIn[q] == '-') { // range p = q + 1; // skip spaces after dash while (p < len && (arrBufferIn[p] == ' ' || arrBufferIn[p] == '\t')) ++p; // parse second number if (p >= len || arrBufferIn[p] < '0' || arrBufferIn[p] > '9') { // malformed range, treat as single number if (num1 >= 0 && num1 < dbSize) { // add unique bool exists = false; for (int k = 0; k < selCount; ++k) if (pntArrSelected[k] == num1) { exists = true; break; } if (!exists) pntArrSelected[selCount++] = num1; } continue; } int num2 = 0; while (p < len && arrBufferIn[p] >= '0' && arrBufferIn[p] <= '9') { num2 = num2 * 10 + (arrBufferIn[p] - '0'); ++p; } // normalize int start = num1 < num2 ? num1 : num2; int end = num1 < num2 ? num2 : num1; for (int v = start; v <= end; ++v) { if (v < 0 || v >= dbSize) continue; bool exists = false; for (int k = 0; k < selCount; ++k) if (pntArrSelected[k] == v) { exists = true; break; } if (!exists) pntArrSelected[selCount++] = v; } } else { // single index if (num1 >= 0 && num1 < dbSize) { bool exists = false; for (int k = 0; k < selCount; ++k) if (pntArrSelected[k] == num1) { exists = true; break; } if (!exists) pntArrSelected[selCount++] = num1; } // p already at first non-digit (or end), continue parsing loop } } // if after parsing nothing was valid, select all if (selCount == 0) { for (int i = 0; i < dbSize; ++i) pntArrSelected[selCount++] = i; } } // Sort selected indices (simple insertion sort since small N) and remove duplicates if any // Note: duplicates should already be avoided, but ensure order is ascending to match previous behavior. for (int i = 1; i < selCount; ++i) { int key = pntArrSelected[i]; int j = i - 1; while (j >= 0 && pntArrSelected[j] > key) { pntArrSelected[j + 1] = pntArrSelected[j]; --j; } pntArrSelected[j + 1] = key; } // remove duplicates (defensive) int uniqueCount = 0; for (int i = 0; i < selCount; ++i) { if (i == 0 || pntArrSelected[i] != pntArrSelected[i - 1]) { pntArrSelected[uniqueCount++] = pntArrSelected[i]; } } selCount = uniqueCount; return pntArrSelected; } MyVisualObject m_ArrDBVisualObj[11]; //Array sul quale si eseguirà una selezione di elementi void main() { //Si riepie un array, m_ArrDBVisualObj[11], sul quale si vogliono selezionare gli //elementi mediante indice di ciascun suo elemento. //(!) Per ipotesi m_ArrDBVisualObj[11] è già pieno. const int sourceArraySize = sizeof(m_ArrDBVisualObj) / sizeof(m_ArrDBVisualObj[0]); cout << "Elenco elementi disponibili:\n"; for (int i = 0; i < sourceArraySize; ++i) { cout << " [" << i << "] Label=\"" << m_ArrDBVisualObj[i].Label << "\"\n"; } // Chiede all'utente gli indici da copiare nell'array filtrato int* pntArrSelected = AskUser_ArraySelectedIndex(sourceArraySize); // Purtroppo il seguente è l'UNICO METODO PER AVERE LA DIMENSIONE dell'array // puntato da pntArrSelected !!! int selCount = 0; for (int i = 0; i < sourceArraySize; ++i) { if (pntArrSelected[i] >= 0 && pntArrSelected[i] < sourceArraySize) { ++selCount; } else { break; } } //L'esempio reale continua riversando in un nuovo array la selezione fatta grazie a // AskUser_ArraySelectedIndex(() // ... }
Stringhe
Sotto-stringa strstr()
Per cercare una sottostringa ed ottenerne ciò che corrisponde sino alla fine:
#include <iostream> using namespace std; const char* Mia_StrStr(const char* source, const char* toFound) { if (!*toFound) return source; // empty substring matches at start for (; *source; source++) { const char *p1 = source, *p2 = toFound; while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; } if (!*p2) return source; // found substring } return nullptr; } int main() { const char* source = "Testo della poesia nuova!"; const char* toFound = "la"; const char* subStr = Mia_StrStr(source, toFound); if (subStr) cout << subStr << endl;// Output: la poesia nuova! else cout << "NON trovata." << endl; return 0; }
Accodamento stringa-numero
Esempio d'uso di funzione che restituisce una stringa\array di caratteri composto dall'array iniziale seguito dal numero (intero positivo) trasformato anch'esso in array di caratteri.
Caso in cui l'output è un puntatore di arrray di caratteri:
#include <iostream> using namespace std; char* concatNumber(const char* str, int number) { static char result[50]; // buffer statico per risultato // Copia str in result int i = 0; while (str[i] != '\0' && i < 49) { result[i] = str[i]; i++; } // Converti numero in stringa char numStr[12]; int j = 0; if (number == 0) { numStr[j++] = '0'; } else { int temp = number; char rev[10]; int k = 0; while (temp > 0) { rev[k++] = (temp % 10) + '0'; temp /= 10; } // Inverti cifra while (k > 0) { numStr[j++] = rev[--k]; } } numStr[j] = '\0'; // Accoda numStr a result int m = 0; while (numStr[m] != '\0' && i < 49) { result[i++] = numStr[m++]; } result[i] = '\0'; return result; } int main() { const char* s = "Valore: "; int n = 789; cout << concatNumber(s, n) << endl; // Output: Valore: 789 return 0; }
Output:
Valore: 789
Caso in cui in output c'è di arrray di caratteri:
#include <iostream> using namespace std; void concatNumber(const char* str, int number, char result[]) { // Copia str in result int i = 0; while (str[i] != '\0' && i < 49) { result[i] = str[i]; i++; } // Converti numero in stringa char numStr[12]; int j = 0; if (number == 0) { numStr[j++] = '0'; } else { int temp = number; char rev[10]; int k = 0; while (temp > 0) { rev[k++] = (temp % 10) + '0'; temp /= 10; } while (k > 0) { numStr[j++] = rev[--k]; } } numStr[j] = '\0'; // Accoda numStr a result int m = 0; while (numStr[m] != '\0' && i < 49) { result[i++] = numStr[m++]; } result[i] = '\0'; } int main() { const char* s = "Valore: "; int n = 789; char res[50]; concatNumber(s, n, res); cout << res << endl; // Output: Valore: 789 return 0; }
Verifiche
Per determinare se un carattere è un numero possiamo usare la funzione standard std::isdigit<code> quindi aggiungere l'header <cctype>
#include <iostream> #include <cctype> // Necessario per std::isdigit int main() { char c = '7'; if (std::isdigit(c)) { std::cout << c << " e' un numero." << std::endl; } else { std::cout << c << " NON e' un numero." << std::endl; } return 0; }
Array
Ricerche
Stringa in array di stringhe
Esempio con array in input passati per valore.
#include <iostream> using namespace std; void FindStrArrPosition(const char s1[], const char arrToScan[][100], int size, int &position) { position = -1; for (int i = 0; i < size; ++i) { int j = 0; while (s1[j] != '\0' && arrToScan[i][j] != '\0' && s1[j] == arrToScan[i][j]) { ++j; } if (s1[j] == '\0' && arrToScan[i][j] == '\0') { position = i; return; } } } int main() { const char arrToScan[3][100] = {"apple", "banana", "cherry"}; const char s1[] = "banana"; int pos; FindStrArrPosition(s1, arrToScan, 3, pos); cout << "Position: " << pos << endl; // Output: Position: 1 return 0; }
Esempio con array in input passati per REFERENZA. + posizione in output
#include <iostream> using namespace std; int FindStrArrPosition(const char (&s1)[100], const char (&arrToScan)[3][100]) { int position = -1; for (int i = 0; i < 3; ++i) { int j = 0; while (s1[j] != '\0' && arrToScan[i][j] != '\0' && s1[j] == arrToScan[i][j]) { ++j; } if (s1[j] == '\0' && arrToScan[i][j] == '\0') { position = i; return position; } } return position; } int main() { char arrToScan[3][100] = {"apple", "banana", "cherry"}; char s1[100] = "cherry"; int pos = FindStrArrPosition(s1, arrToScan); cout << "Position: " << pos << endl; // Output: Position: 1 return 0; }
CRUD
Cancellazione
Eliminazione di un elemento da un array di stringhe:
#include <iostream> #include <string.h> // for strcpy() using namespace std; const int MAX_STRINGS = 5; const int MAX_LENGTH = 20; void DeleteString(char arr[][MAX_LENGTH], int& count, int indexToDelete) { if (indexToDelete < 0 || indexToDelete >= count) { cout << "Invalid index to delete." << endl; return; } for (int i = indexToDelete; i < count - 1; i++) { strcpy(arr[i], arr[i + 1]); } count--; } int main() { char arr[MAX_STRINGS][MAX_LENGTH] = { "Uno", "Due", "Tre", "Quattro", "Cinque" }; int count = 5; cout << "Before deletion:" << endl; for (int i = 0; i < count; i++) { cout << arr[i] << endl; } DeleteString(arr, count, 2); // delete "Tre" cout << "\nAfter deletion:" << endl; for (int i = 0; i < count; i++) { cout << arr[i] << endl; } return 0; }
Eliminazione di un elemento da un array di interi:
#include <iostream> using namespace std; const int MAX_SIZE = 10; void DeleteInt(int arr[], int& count, int indexToDelete) { if (indexToDelete < 0 || indexToDelete >= count) { cout << "Invalid index to delete." << endl; return; } for (int i = indexToDelete; i < count - 1; i++) { arr[i] = arr[i + 1]; } count--; } int main() { int arr[MAX_SIZE] = {10, 20, 30, 40, 50, 60}; int count = 6; cout << "Before deletion:" << endl; for (int i = 0; i < count; i++) { cout << arr[i] << " "; } cout << endl; DeleteInt(arr, count, 2); // delete item at index 2 (30) cout << "After deletion:" << endl; for (int i = 0; i < count; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
Aggiunta
#include <iostream> #include <string.h> using namespace std; const int MAX_STRINGS = 10; const int MAX_LENGTH = 20; char m_ArrDBVisualObj[MAX_STRINGS][MAX_LENGTH] = { "Uno", "Due", "Tre", "Quattro", "Cinque", "Sei", "Sette", "", "", "" }; int m_DBCount = 7; char m_ArrFilterVisualObj[MAX_STRINGS][MAX_LENGTH] = { "Uno", "Tre", "", "", "", "", "", "", "", "" }; int m_FilterCount = 2; // Insert item from m_ArrDBVisualObj into m_ArrFilterVisualObj at the same index // Both counts and arrays passed by reference void AddItemToFilter(char (&dbArr)[MAX_STRINGS][MAX_LENGTH], int& dbCount, char (&filterArr)[MAX_STRINGS][MAX_LENGTH], int& filterCount, int indexToAdd) { if (indexToAdd < 0 || indexToAdd >= dbCount) { cout << "Invalid index to add." << endl; return; } // Shift elements right to open space at indexToAdd for (int i = filterCount; i > indexToAdd; i--) { strcpy(filterArr[i], filterArr[i - 1]); } // Copy the item from database array strcpy(filterArr[indexToAdd], dbArr[indexToAdd]); filterCount++; } int main() { cout << "Filter before addition (count=" << m_FilterCount << "):" << endl; for (int i = 0; i < m_FilterCount; i++) { cout << i << ": " << m_ArrFilterVisualObj[i] << endl; } AddItemToFilter(m_ArrDBVisualObj, m_DBCount, m_ArrFilterVisualObj, m_FilterCount, 1); cout << "\nFilter after addition (count=" << m_FilterCount << "):" << endl; for (int i = 0; i < m_FilterCount; i++) { cout << i << ": " << m_ArrFilterVisualObj[i] << endl; } return 0; }
Output:
Filter before addition (count=2): 0: Uno 1: Tre Filter after addition (count=3): 0: Uno 1: Due 2: Tre
Strutture dinamiche
Vector
Un "<code>vector" è una collezione di oggetti tutti dello stesso tipo. Ogni oggetto della collezione ha associato un indice che ne consente l'accesso a questo oggetto.
Un vector può gestire oggetti di diversi tipi ma poiché i tipi referenza non sono oggetti, i vector non possono gestire i tipi referenza (Es. int &refVal = variabileIntera;).
#include <vector> using std::vector; //Esempio di INIZIALIZZAZIONE vettori di diversi tipi: vector<int> vttInt; //vttInt è un vettore di oggetti di tipo intero vector<Sales_item> vtt_Sales; //Vettore di oggetti di tipo Sales_item vector<vector<string>> vttVttFile; //Vettore di vettori di stringhe
PS sul C++ di Arduino normalmente non è possibile usare i vector...
Copia
vector<string> svec; //default initialization; vector<int> ivec2(ivec);//copy elements of ivec into ivec2 vector<int> ivec3 = ivec;//copy elements of ivec into ivec3 vector<string> svec(ivec2);//error: svec holds strings, not ints
ToDo ... da esplorare e riportare ... incompleto
etc
XML:
(Mappa e Link)
C# | Visual Studio | MS SQL | Dizionario
Parole chiave:
