|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Apr 2008
Messaggi: 101
|
[C#] Formattazione spazi di un testo
Salve a tutti!
Sono un novellino nella programmazione C# e mi sarebbe piaciuto porgervi un mio problema che non riesco a risolvere Ho una testbox, che viene popolata da una stringa di testo che purtroppo presenta diversi spazi al suo interno: vi faccio un esempio del genere... Questo è un programma C# . . . . . . fatto da me. Come potete notare ci sono un sacco di spazi (li ho indicati coi puntini) tra: C# e fatto da me... Ecco, come potrei fare per rimuovere tutti quegli spazi e lasciarne così uno solo? Del tipo: Questo è un programma C# fatto da me. Vi ringrazio anticipatamente per il vostro tempo dedicatomi
__________________
CPU: Intel Core 2 Quad [email protected] cooled by Cooler Master Gemini II (413x8, FSB@1652Mhz, 1.44v) MB: Gigabyte GA-P45-UD3LR Ram: 4GB DDR2@826Mhz (5-7-7-20) Sk Video: XFX8800GT A.D. Edition XXX (GPU: 670Mhz, MEM: 1950Mhz, GDDR3 512Mb) HDD: 2xMaxtor DiamondMax 160GB 8Mb 7200rpm + Seagate 1Tb Alimentatore: Corsair TX650W Schermo: LCD ASUS VW222 22" Casse: Creative 5.1 S.O.: Windows 7 Ultimate 64bit Adsl (Down/Up): Fastweb 7Mbit / 512Kb Multimedia HDD: Iomega ScreenPlay Director HD 1Tb |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
Codice:
while (stringa.Contains(" "))
stringa = stringa.Replace(" ", " ");
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Apr 2008
Messaggi: 101
|
Ti ringrazio per la risposta ||ElChE||88 !
Il fatto è che usando quel codice, il programma mi entra il un loop infinito nel while sembrerebbe e, dato che la textbox la popolo nel formload, il form non viene appunto mai caricato Non saprei qualcuno ha qualche altra idea?
__________________
CPU: Intel Core 2 Quad [email protected] cooled by Cooler Master Gemini II (413x8, FSB@1652Mhz, 1.44v) MB: Gigabyte GA-P45-UD3LR Ram: 4GB DDR2@826Mhz (5-7-7-20) Sk Video: XFX8800GT A.D. Edition XXX (GPU: 670Mhz, MEM: 1950Mhz, GDDR3 512Mb) HDD: 2xMaxtor DiamondMax 160GB 8Mb 7200rpm + Seagate 1Tb Alimentatore: Corsair TX650W Schermo: LCD ASUS VW222 22" Casse: Creative 5.1 S.O.: Windows 7 Ultimate 64bit Adsl (Down/Up): Fastweb 7Mbit / 512Kb Multimedia HDD: Iomega ScreenPlay Director HD 1Tb Ultima modifica di J0k3r91 : 17-11-2008 alle 18:13. |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
Quote:
Codice:
string text = textBox1.Text;
while (text.Contains(" "))
text = text.Replace(" ", " ");
|
|
|
|
|
|
|
#5 |
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Soluzione in stile C:
Codice:
static string EliminaSpazi(string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
if (str[i] != ' ' && str[i] != '\t')
{
sb.Append(str[i]);
}
else
{
sb.Append(' ');
while (str[i] == ' ' || str[i] == '\t')
i++;
i--;
}
}
return sb.ToString().Trim();
}
static void Main(string[] args)
{
Console.WriteLine();
string str = "questo e' un programma C# fatto da me";
Console.WriteLine(str);
str = EliminaSpazi(str);
Console.WriteLine(str);
}
Ultima modifica di Vincenzo1968 : 17-11-2008 alle 18:25. |
|
|
|
|
|
#6 | |
|
Member
Iscritto dal: Apr 2008
Messaggi: 101
|
Quote:
Codice:
string strpro = queryObj["Name"].ToString();
while (strpro.Contains(" "))
{
ProcessoreBox.Text = strpro.Replace(" ", " ");
}
![]() Dimmi se sbaglio...
__________________
CPU: Intel Core 2 Quad [email protected] cooled by Cooler Master Gemini II (413x8, FSB@1652Mhz, 1.44v) MB: Gigabyte GA-P45-UD3LR Ram: 4GB DDR2@826Mhz (5-7-7-20) Sk Video: XFX8800GT A.D. Edition XXX (GPU: 670Mhz, MEM: 1950Mhz, GDDR3 512Mb) HDD: 2xMaxtor DiamondMax 160GB 8Mb 7200rpm + Seagate 1Tb Alimentatore: Corsair TX650W Schermo: LCD ASUS VW222 22" Casse: Creative 5.1 S.O.: Windows 7 Ultimate 64bit Adsl (Down/Up): Fastweb 7Mbit / 512Kb Multimedia HDD: Iomega ScreenPlay Director HD 1Tb |
|
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Apr 2008
Messaggi: 101
|
Grazie mille davvero Vincenzo1968!
Ha funzionato perfettamente! Certo che c'è una bella massa di codice per fare una cosa apparentemente banale... Grazie ancora!
__________________
CPU: Intel Core 2 Quad [email protected] cooled by Cooler Master Gemini II (413x8, FSB@1652Mhz, 1.44v) MB: Gigabyte GA-P45-UD3LR Ram: 4GB DDR2@826Mhz (5-7-7-20) Sk Video: XFX8800GT A.D. Edition XXX (GPU: 670Mhz, MEM: 1950Mhz, GDDR3 512Mb) HDD: 2xMaxtor DiamondMax 160GB 8Mb 7200rpm + Seagate 1Tb Alimentatore: Corsair TX650W Schermo: LCD ASUS VW222 22" Casse: Creative 5.1 S.O.: Windows 7 Ultimate 64bit Adsl (Down/Up): Fastweb 7Mbit / 512Kb Multimedia HDD: Iomega ScreenPlay Director HD 1Tb |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Questo e' in stile C#
Codice:
string input = "Pazzo Pezzo Pizzo Pozzo P*zzo "; string output = Regex.Replace(input, @"\s+", " "); (Poi quanto in genere siano leggibili le Regular Expression e' un altro discorso)
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 17-11-2008 alle 19:13. |
|
|
|
|
|
#9 | |
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Una versione migliore della funzione EliminaSpazi: Codice:
static string EliminaSpazi(string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
if (str[i] != ' ' && str[i] != '\t')
{
sb.Append(str[i]);
}
else
{
sb.Append(' ');
while (i < str.Length && (str[i] == ' ' || str[i] == '\t'))
i++;
i--;
}
}
return sb.ToString().Trim();
}
|
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Mmmh...
un codice con un ciclo for il cui contatore viene cambiato all'interno del ciclo stesso, e per di piu' con anche un i-- viene chiamato Ma quella faccia che mi hai piazzato come commento cosa significa?
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#11 | |
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Sarà spaghetti code ma, dal punto di vista delle performance, per come, dico, sono implementate le regex nei vari linguaggi, non c'è paragone: http://swtch.com/~rsc/regexp/regexp1.html Per quanto riguarda la leggibilità, non vedo cosa ci sia di poco leggibile in quelle poche righe di codice. L'algoritmo è semplice: 1) Leggiamo la stringa di input un carattere alla volta. 2) Se non è uno spazio, aggiungiamo il carattere letto alla stringa di output. 3) Se è uno spazio, aggiungiamo un carattere spazio alla stringa di output e incrementiamo il contatore(la variabile indice i) finchè il carattere letto è uno spazio; così facendo saltiamo tutti gli spazi superflui. 4) All'uscita dal ciclo while dobbiamo decrementare il contatore di una unità, altrimenti salteremmo il primo carattere della parola successiva. È, bene o male, la stessa tecnica utilizzata dai compilatori per l'analisi lessicale. Ultima modifica di Vincenzo1968 : 17-11-2008 alle 19:45. |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Se proprio lo dovessi fare senza Regex, (e non lo farei), lo farei cosi'
Codice:
string input = "Pazzo Pezzo Pizzo Pozzo P*zzo ";
StringWriter outputStream = new StringWriter();
bool previousspace = false;
foreach (char ch in input)
{
if (char.IsWhiteSpace(ch))
{
if (!previousspace)
{
outputStream.Write(ch);
}
previousspace = true;
}
else
{
outputStream.Write(ch);
previousspace = false;
}
}
string output = outputStream.ToString();
Lo vedo che non c'e' nulla di complesso in quel codice. Ma se fra un anno io leggo la mia Regex la capisco subito. La Regex descrive un comportamento. Se devo leggere il tuo codice o il mio ultimo, prima di dire "Fa questo!", devo simulare, devo seguire, devo capire, insomma, devo fare il lavoro del compilatore. Il discorso della velocita'. Spero sia chiaro che chi sceglie C# non lo sceglie per la velocita' di esecuzione. Ma per la aumentare la velocita' di scrittura, diminuire gli errori e semplificare la fase di debug e la manutenzione (rispetto a C e C++)
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 17-11-2008 alle 20:39. |
|
|
|
|
|
#13 | ||
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Codice:
/* 1) Leggiamo la stringa di input un carattere alla volta. 2) Se non è uno spazio, aggiungiamo il carattere letto alla stringa di output. 3) Se è uno spazio, aggiungiamo un carattere spazio alla stringa di output e incrementiamo il contatore(la variabile indice i) finchè il carattere letto è uno spazio; così facendo saltiamo tutti gli spazi superflui. 4) All'uscita dal ciclo while dobbiamo decrementare il contatore di una unità, altrimenti salteremmo il primo carattere della parola successiva. */ ... segue la definizione della funzione Quote:
|
||
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
Inoltre, riguardo alle prestazioni, quanti nanosecondi credi che guadagneresti con il tuo lunghissimo codice rispetto alla regex su un'unica stringa (come da requisiti)? ![]() EDIT: dimenticavo. Inoltre i commenti non devono assolutamente spiegare quello che fa il codice ma piuttosto il motivo per cui viene fatta quell'operazione. Ad esempio se io chiamo una funzione removeSpaces() è già chiarissimo il suo compito ed è inutile commentare scrivendo //Rimuove gli spazi. Invece *potrebbe* essere utile spiegare il motivo per cui si vogliono eliminare gli spazi, e quindi in questo caso sarebbe //formatta correttamente la stringa restituita da WMI.
__________________
Ultima modifica di ^TiGeRShArK^ : 17-11-2008 alle 20:59. |
|
|
|
|
|
|
#15 | |
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
P.S sull'inutilità dei commenti nel codice, avrei molto da obiettare. |
|
|
|
|
|
|
#16 | ||
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
per quanto riguarda i commenti in questo post: http://www.codinghorror.com/blog/archives/000749.html è spiegato piuttosto bene perchè i commenti devono spiegare solo il perchè di un certo codice e non la funzionalità del codice. e citando Martin Fowler: Quote:
__________________
|
||
|
|
|
|
|
#17 |
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Codice:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics;
namespace EliminaSpazi
{
class Program
{
static string EliminaSpazi(string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
if (str[i] != ' ' && str[i] != '\t')
{
sb.Append(str[i]);
}
else
{
sb.Append(' ');
while (i < str.Length && (str[i] == ' ' || str[i] == '\t'))
i++;
i--;
}
}
return sb.ToString().Trim();
}
static string EliminaSpaziGugo2(string str)
{
string input = "Pazzo Pezzo Pizzo Pozzo P*zzo ";
StringWriter outputStream = new StringWriter();
bool previousspace = false;
foreach (char ch in input)
{
if (char.IsWhiteSpace(ch))
{
if (!previousspace)
{
outputStream.Write(ch);
}
previousspace = true;
}
else
{
outputStream.Write(ch);
previousspace = false;
}
}
return outputStream.ToString();
}
static string EliminaSpaziGugo(string str)
{
return Regex.Replace(str, @"\s+", " ");
}
static void Main(string[] args)
{
string str = "Pazzo Pezzo Pizzo Pozzo P*zzo ";
string[] stringhe = new string[100000];
Console.WriteLine();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100000; i++)
stringhe[i] = EliminaSpazi(str);
sw.Stop();
Console.WriteLine("Tempo impiegato me medesimo -> {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000; i++)
stringhe[i] = EliminaSpaziGugo(str);
sw.Stop();
Console.WriteLine("Tempo impiegato Gugo 1 -> {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < 100000; i++)
stringhe[i] = EliminaSpaziGugo2(str);
sw.Stop();
Console.WriteLine("Tempo impiegato Gugo 2 -> {0} ms", sw.ElapsedMilliseconds);
//Console.WriteLine(stringhe[0]);
//Console.WriteLine(stringhe[99999]);
}
}
}
Ultima modifica di Vincenzo1968 : 18-11-2008 alle 00:45. |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Non hai capito.
Scrivilo in C allora. Oppure in Assembly, perche' rinunciarvi? Se veramente volessi la velocita', oppure quando mi servisse la velocita', passerei ad un C++ ben scritto. Ebbene, in 5 anni di C# non mi e' mai servita la velocita' al punto da scendere a compromessi con leggibilita', manutenabilita', autodescrizione. E non sono mai passato al C++, se non proprio quando non ne potevo fare a meno, e non era per questioni di velocita'. Su un progetto vivo, una riga di codice vive poco, molto meno rispetto al totale. La maggior parte delle volte e' inutile addirittura ottimizzare. Meglio rifattorizzare. E il target e' quello di scrivere meno codice possibile. Meno codice equivale a meno errori, e spesso anche a piu' prestazioni. Comunque se vuoi ti mostro un paio di trucchi. Prova a trasformare il mio foreach in un ciclo for semplice e rifai i calcoli... E prova a cambiare lo StringWriter in uno StringBuilder. char.IsWhiteSpace fa qualcosa in piu' di un semplice controllo con spazio. Gli "spazi" sono tanti. E le Regex comunque si possono compilare una volta per tutte. Si puo' mangiare qualcosa anche li'. Riprendo. Se vuoi la velocita', se non programmi in gruppo, se non riscrivi il codice, se rileggi solo codice scritto da te, non usare il C#. Ma fai attenzione. Fra qualche anno, neppure troppi, i linguaggi descrittivi corredati da compilatori con le palle, potranno anche rischiare di superare in velocita' i monolitici come il C o il C++ usati in modo classico. Riprova fra 5/6 anni i nostri contest, penso che avrai delle suorprese.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#19 | |||||
|
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Quote:
Quote:
Quote:
Quote:
P.S per quanto riguarda la leggibilità, tenendo conto di quello che ha scritto Tiger, personalmente penso che, tra un anno, troverei più facile capire il codice che ho scritto io(o la tua seconda soluzione) piuttosto che quell'unica riga di codice con l'espressione regolare: @"\s+", " " (penso farei questa faccia: |
|||||
|
|
|
|
|
#20 | ||
|
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
ora dividi il secondo impiegato dal codice con la regex per 100000 e guarda la differenza con il tuo codice. Una differenza di un paio di microsecondi è davvero così importante? Devo ricordarti che in caso di una query WMI il collo di bottiglia non è assolutamente l'elaborazione del risultato restituito tramite regex? E' perfettamente inutile scrivere un codice che su 100000 file da elaborare è 5 volte + veloce quando il requisito del problema ci dice chiaramente che questo metodo va applicato una volta (o, nel caso peggiore, una volta su ogni stringa restituita da WMI) e dunque le differenze di velocità sono nell'ordine dei microsecondi. Quote:
la @ serve per inserire in una stringa caratteri con backslash senza duplicarlo, lo \s indica i caratteri considerati spazio (\t\r\n\v\f) e il + indica che deve esserci almeno un elemento presente. Quindi il significato del metodo utilizzato è: sostituisci tutti i caratteri in cui vi sia almeno uno spazio consecutivo con uno spazio singolo. Per fare quanto richiesto dal problema in realtà sarebbe bastato utilizzare " +" che mi pare assolutamente banale da capire.... Comunque se hai un pò di fantasia prova a sostituire nel tuo bench @" \s+" con " +" per vedere come si sarebbero comportate prestazionalmente le regex nel caso reale. E, volendo, ci sarebbe anche la compilazione da fare. Ma, come dicevo prima, in questo caso è uno sbattimento assolutamente inutile e, anzi, peggiora le prestazioni dato il ridottissimo numero di esecuzioni di questo metodo.
__________________
|
||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:12.




















