Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite
Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite
Abbiamo guidato per diversi giorni la Alpine A290, la prima elettrica del nuovo corso della marca. Non è solo una Renault 5 sotto steroidi, ha una sua identità e vuole farsi guidare
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile
Abbiamo provato a fondo il nuovo Magic 8 Lite di HONOR, e per farlo siamo volati fino a Marrakech , dove abbiamo testato la resistenza di questo smartphone in ogni condizione possibile ed immaginabile. Il risultato? Uno smartphone praticamente indistruttibile e con un'autonomia davvero ottima. Ma c'è molto altro da sapere su Magic 8 Lite, ve lo raccontiamo in questa recensione completa.
Sony WF-1000X M6: le cuffie in-ear di riferimento migliorano ancora
Sony WF-1000X M6: le cuffie in-ear di riferimento migliorano ancora
WF-1000X M6 è la sesta generazione di auricolare in-ear sviluppata da Sony, un prodotto che punta a coniugare facilità di utilizzo con una elevata qualità di riproduzione dei contenuti audio e una cura nella riduzione del rumore ambientale che sia da riferimento
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 22-01-2012, 02:39   #1
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
[C++] Funzione cancella stringa

Ho provato a fare questo esercizio:
ho due stringhe (come array di char) A={"CIAO"}; B={"AI"}.
Devo eliminare in A ogni lettera presente in B e mettere la nuova parola in un nuovo array di char C.
Ho pensato di controllare le lettere uguali con due for e di inserire asterischi al posto delle lettere uguali in A. poi successivamente vado a mettere nell array C solo le lettere diverse da asterisco.
Dovrebbe stampare la stringa CO invece stampa COAI. cosa non va?
CODICE
Codice:
#include <iostream>
using namespace std;

void cancella(char A[], char B[], char C[]);

int main(){
    char A[]={"CIAO"};
    char B[]={"AI"};
    char C[]={" "};
    
    cancella(A,B,C);
    for(int i=0; i<strlen(C); i++)
    cout<<C[i]<<endl;
    
system("pause");
return 0;
}

void cancella(char A[], char B[], char C[]){
     int n=0;
     for(int i=0; i<strlen(A); i++){
             for(int j=0; j<strlen(B); j++){
                     if(A[i]==B[j])
                     A[i]='*';
                     
                     }
             }
     for(int k=0; k<strlen(A); k++){
             if(A[k]!='*')
             C[n++]=A[k];
             }
}
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 22-01-2012, 10:11   #2
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da mistergks Guarda i messaggi
Ho provato a fare questo esercizio:
ho due stringhe (come array di char) A={"CIAO"}; B={"AI"}.
Devo eliminare in A ogni lettera presente in B e mettere la nuova parola in un nuovo array di char C.
Ho pensato di controllare le lettere uguali con due for e di inserire asterischi al posto delle lettere uguali in A. poi successivamente vado a mettere nell array C solo le lettere diverse da asterisco.
Dovrebbe stampare la stringa CO invece stampa COAI. cosa non va?
CODICE
Codice:
#include <iostream>
using namespace std;

void cancella(char A[], char B[], char C[]);

int main(){
    char A[]={"CIAO"};
    char B[]={"AI"};
    char C[]={" "};
    
    cancella(A,B,C);
    for(int i=0; i<strlen(C); i++)
    cout<<C[i]<<endl;
    
system("pause");
return 0;
}

void cancella(char A[], char B[], char C[]){
     int n=0;
     for(int i=0; i<strlen(A); i++){
             for(int j=0; j<strlen(B); j++){
                     if(A[i]==B[j])
                     A[i]='*';
                     
                     }
             }
     for(int k=0; k<strlen(A); k++){
             if(A[k]!='*')
             C[n++]=A[k];
             }
}
Gli array non sanno che dimensione hanno, e per di più ridimensionarli è un casino. Non aumentano la loro dimensione da soli se gli dai un indice più grande del loro range. Quindi quando scrivi C[n++], quando n > 0, chissà cosa succede in memoria. Io ho questo output con strlen(C) == 14:
Codice:
C
O
[
[
[
[
[
[
[
[
[
[
A
I
Quindi direi che il minimo è dimensionare, nel main, C uguale ad A:
Codice:
char A[100] = {"CIAO"};
char C[100];
Non so bene come fare il ridimensionamento dinamico con malloc() perchè gli array praticamente non li ho mai usati, meglio usare vector che sono ridimensionabili e hanno un sacco di funzioni.
C'è un altro "errore":
Codice:
C[n++] = A[k];
è sbagliato concettualmente perchè il risultato è equivalente a:
Codice:
C[n] = A[k];
++n;
ma rischi di sbagliare in quanto l'ordine di priorità rispetto ad altri operatori potrebbe non essere quello che ti aspetti. Inoltre se leggi 2 volte in una riga il valore di una variabile che in quella stessa riga viene scritta il risultato è indefinito (così dice il creatore del C++): espressioni tipo
Codice:
(++i) + (++i)
sono indefinite. Il codice funzionante è questo:
Codice:
#include <iostream>

using namespace std;

void cancella(char A[], char B[], char C[]);

int main() {
	char A[100] = {"CIAO"};
	char B[100] = {"AI"};
	char C[100] = {""};
    
	cancella(A,B,C);
	for(int i = 0; i < strlen(A); ++i) cout << A[i];
	cout << "\nstrlen(A) = " << strlen(A) << endl;
	for(int i = 0; i < strlen(B); ++i) cout << B[i];
	cout << "\nstrlen(B) = " << strlen(A) << endl;
	for(int i = 0; i < strlen(C); ++i) cout << C[i];
	cout << "\nstrlen(C) = " << strlen(C) << endl;

	system("pause");
	return 0;

	int i = 1;
	int j = ++i + i++;
	cout << endl << endl << j << endl << endl;
}

void cancella(char A[], char B[], char C[]) {
	int n = 0;
	for (int i = 0; i < strlen(A); ++i) {
		for (int j = 0; j < strlen(B); ++j) {
				if (A[i] == B[j]) A[i] = '*';
                                break;
		}
	}
    
	for (int k = 0; k < strlen(A); ++k) {
		if (A[k] != '*') {
			C[n] = A[k];
			++n;
		}
	}
}

Ultima modifica di vendettaaaaa : 22-01-2012 alle 10:15.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 23-01-2012, 13:20   #3
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
Quote:
Originariamente inviato da vendettaaaaa Guarda i messaggi
Gli array non sanno che dimensione hanno, e per di più ridimensionarli è un casino. Non aumentano la loro dimensione da soli se gli dai un indice più grande del loro range. Quindi quando scrivi C[n++], quando n > 0, chissà cosa succede in memoria. Io ho questo output con strlen(C) == 14:
Codice:
C
O
[
[
[
[
[
[
[
[
[
[
A
I
Quindi direi che il minimo è dimensionare, nel main, C uguale ad A:
Codice:
char A[100] = {"CIAO"};
char C[100];
Non so bene come fare il ridimensionamento dinamico con malloc() perchè gli array praticamente non li ho mai usati, meglio usare vector che sono ridimensionabili e hanno un sacco di funzioni.
C'è un altro "errore":
Codice:
C[n++] = A[k];
è sbagliato concettualmente perchè il risultato è equivalente a:
Codice:
C[n] = A[k];
++n;
ma rischi di sbagliare in quanto l'ordine di priorità rispetto ad altri operatori potrebbe non essere quello che ti aspetti. Inoltre se leggi 2 volte in una riga il valore di una variabile che in quella stessa riga viene scritta il risultato è indefinito (così dice il creatore del C++): espressioni tipo
Codice:
(++i) + (++i)
sono indefinite. Il codice funzionante è questo:
Codice:
#include <iostream>

using namespace std;

void cancella(char A[], char B[], char C[]);

int main() {
	char A[100] = {"CIAO"};
	char B[100] = {"AI"};
	char C[100] = {""};
    
	cancella(A,B,C);
	for(int i = 0; i < strlen(A); ++i) cout << A[i];
	cout << "\nstrlen(A) = " << strlen(A) << endl;
	for(int i = 0; i < strlen(B); ++i) cout << B[i];
	cout << "\nstrlen(B) = " << strlen(A) << endl;
	for(int i = 0; i < strlen(C); ++i) cout << C[i];
	cout << "\nstrlen(C) = " << strlen(C) << endl;

	system("pause");
	return 0;

	int i = 1;
	int j = ++i + i++;
	cout << endl << endl << j << endl << endl;
}

void cancella(char A[], char B[], char C[]) {
	int n = 0;
	for (int i = 0; i < strlen(A); ++i) {
		for (int j = 0; j < strlen(B); ++j) {
				if (A[i] == B[j]) A[i] = '*';
                                break;
		}
	}
    
	for (int k = 0; k < strlen(A); ++k) {
		if (A[k] != '*') {
			C[n] = A[k];
			++n;
		}
	}
}
a me il tuo codice stampa:
Codice:
CI*O
strlen(A)=4;
AI
strlen(B)=4
CIO
strlen(C)=3
non dovrebbe stamparmi la stringa CO alla fine?!toglie solo la A?
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 23-01-2012, 15:05   #4
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Non mi ricordo perchè ma dopo aver testato il codice ho aggiunto un break nel ciclo for che cancella le lettere di A, è quello il problema.
Ora ricordo, il break l'ho aggiunto qui direttamente nel post ma andrebbe nel blocco if che sta nel blocco for (j = 0...):
Codice:
void cancella(char A[], char B[], char C[]) {
	int n = 0;
	for (int i = 0; i < strlen(A); ++i) {
		for (int j = 0; j < strlen(B); ++j) {
			if (A[i] == B[j]) {
				A[i] = '*';
				break;
			}
		}
	}
Così se la lettera di A viene trovata in B, viene cancellata e viene interrotta la scansione di B per risparmiare preziosissimi cicli di clock

Alternativamente si può fare così:
Codice:
void cancella(char A[], char B[], char C[]) {
	int n = 0;
	for (int j = 0; j < strlen(B); ++j) {
		for (int i = 0; i < strlen(A); ++i) {
			if (B[j] == A[i]) A[i] = '*';
		}
	}
Che mi pare meglio nel caso A contenga lettere ripetute (prova con "CIAAAAAO").

Ultima modifica di vendettaaaaa : 23-01-2012 alle 15:14.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Alpine A290 alla prova: un'auto bella che ti fa innamorare, con qualche limite Alpine A290 alla prova: un'auto bella che ti fa ...
Recensione HONOR Magic 8 Lite: lo smartphone indistruttibile e instancabile Recensione HONOR Magic 8 Lite: lo smartphone ind...
Sony WF-1000X M6: le cuffie in-ear di riferimento migliorano ancora Sony WF-1000X M6: le cuffie in-ear di riferiment...
Snowflake porta l'IA dove sono i dati, anche grazie a un accordo con OpenAI Snowflake porta l'IA dove sono i dati, anche gra...
Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo M...
Desktop piccolo e potente? NZXT H2 Flow ...
Logan Paul vende la sua carta Pokemon &q...
Polestar spinge sull'acceleratore: arriv...
Nuovo record mondiale nel fotovoltaico: ...
L'ultimo baluardo cade: fine supporto pe...
'Il mondo non ha mai visto nulla di simi...
La Commissione europea mette sotto indag...
Arriva il primo computer quantistico ad ...
'Se lavori al PC sei a rischio': la prev...
Windows 11 introduce il supporto nativo ...
Apple AirDrop su Android: dopo Pixel 10,...
Upgrade PC senza spendere una fortuna: G...
Sistema di sblocco alla iPhone anche su ...
29 offerte Amazon, rinnovate: in 2 minut...
Offerte imperdibili su lavatrici e asciu...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 15:39.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v