Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755

    Problema con StringBuilder

    In un mio programma java utilizzo uno StringBuilder per comporre una stringa,fin qui niente di strano...successivamente invoco un metodo per la lettura del contenuto di un file di testo...e a questo punto sorge il problema...vi posto in linea di massima cosa accade col codice:

    codice:
    public static String metodo (){
           StringBuilder sb=new StringBuilder ();
           ...
           sb.append (unaStringa);
           ...
           sb.append (altraStringa);
           ...
           String s=read (nomeFile , "UTF-8");
           sb.append (s);
           ...
           sb.append (ultimaStringa);
    
           return sb.toString();
    }
    
    public static String read(String fileName,String charSet){
    		BufferedReader buffRead=null;
    		StringBuilder strBuff=new StringBuilder();
    		try{
    			buffRead=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),charSet));
    			String str;
    			while((str=buffRead.readLine())!=null){
    				strBuff.append(str+"\r\n");
    			}
    			buffRead.close();
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		return strBuff.toString();
    }
    Alla fine del metodo "metodo ()" la stringa restituita dovrebbe essere "contenutoPrecedenteStringBuilder+ultimaString a"

    mentre quello che avviene è che ultimaStringa sovrascrive partendo da sinistra il contenuto precedente dello StringBuilder...

    perchè ho questo problema?come posso risolvere?

    Ps. anche provando a fare alla fine "return sb.toString()+ultimaStringa;" avviene la sovrascrittura , ma non riesco a capire il perchè

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Problema con StringBuilder

    Originariamente inviato da zipangulu
    Alla fine del metodo "metodo ()" la stringa restituita dovrebbe essere "contenutoPrecedenteStringBuilder+ultimaString a"

    mentre quello che avviene è che ultimaStringa sovrascrive partendo da sinistra il contenuto precedente dello StringBuilder...
    Nel pezzo che hai postato, nonostante sia solo parziale, io non vedo nulla di strano o palesemente errato.

    Domanda: su che S.O. stai lavorando? Dove è che stampi/visualizzi la stringa? Cioè, per aver visto quell'effetto, da qualche parte la fai vedere. Su una console?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    SO : Windows 7 32 bit
    stampo sulla classica console di default ( ex: System.out.println(blaBlaBla) )

    Per darti un esempio "più pratico" prova a compilare ed eseguire il seguente codice,dovresti riscontrare il problema sopra citato:


    codice:
    import java.io.*;
    
    class Prova{
    	public static String metodo (){
    		StringBuilder sb=new StringBuilder ();
    		sb.append("ma ciao");
    		sb.append ("maramao perchè sei morto");
    		sb.append(read(nomeFile,"UTF-8"));
    		sb.append("maramaopercheseimorto");
    		return sb.toString();
    	}
    
    	public static String read(String fileName,String charSet){
    			BufferedReader buffRead=null;
    			StringBuilder strBuff=new StringBuilder();
    			try{
    				buffRead=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),charSet));
    				String str;
    				while((str=buffRead.readLine())!=null){
    					strBuff.append(str+"\r\n");
    				}
    				buffRead.close();
    			}catch(Exception e){
    				e.printStackTrace();
    			}
    			return strBuff.toString();
    	}
    
    	public static void main (String [] args){
    		System.out.println (metodo ());
    	}
    }

    ovviamente al posto di nomeFile metti un qualsiasi nome/percorso di un tuo file di testo...

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    potrebbe essere la causa il fatto del non "thread-safer" dello StringBuilder e il fatto che il file di testo da leggere è piuttosto grande? mmm...però a meno che non lo riesca a notare,sto lavorando su un unico thread

    EDIT: mi sono appena accort che sull'esempio sopra postato l'anomalia non si manifesta...ti posterò il caso reale dove compare...

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da zipangulu
    potrebbe essere la causa il fatto del non "thread-safer" dello StringBuilder
    No. È vero che StringBuilder (a differenza di StringBuffer) non è "sincronizzato" ma il problema ci sarebbe solo se fosse condiviso tra più thread senza le dovute accortezze. Ma siccome lo StringBuilder lo tieni in una variabile locale e lo usi solo in quel metodo, allora quella certa istanza la usa solo il thread che sta eseguendo quei metodi. Insomma è comunque thread-safe questo uso di StringBuilder.

    Originariamente inviato da zipangulu
    e il fatto che il file di testo da leggere è piuttosto grande?
    Uhm .. penserei di no.

    Originariamente inviato da zipangulu
    EDIT: mi sono appena accort che sull'esempio sopra postato l'anomalia non si manifesta...ti posterò il caso reale dove compare...
    Sì infatti a me non dà problemi (ho preso un sorgente C che avevo a portata di mano come file da leggere).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    Ecco il codice reale,riguarda il calcolo del codice fiscale...il problema sorge nelle ultime righe del metodo "calcola(....)"
    ho scritto due commenti nel main per spiegarti l'anomalia...

    codice:
    import java.util.Arrays;
    import java.io.*;
    
    
    class CalcolaCodice{
    	private static final char [] vocali = {'a','e','i','o','u'};
    	private static final char [] consonanti = {'b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'};
    	private static final char [] lettereMesi = {'a','b','c','d','e','h','l','m','p','r','s','t'};
    	private static final int [] controlloDispari = {1,0,5,7,9,13,15,17,19,21,1,0,5,7,9,13,15,17,19,21,2,4,18,20,11,3,6,8,12,14,16,10,22,25,24,23};
    	private static final int [] controlloPari = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
    	private static final char [] controlloCaratteri = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    	private static final char [] alfabeto = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    	public static String calcola (String cognome , String nome , int giorno , int mese , int anno , char sesso , String comuneNascita) {
    		StringBuilder sb= new StringBuilder ();
    		//COGNOME
    		int lettereCognome=3;
    		char carattere;
    		for(int i=0;i<cognome.length() && lettereCognome>0 ; i++){
    			carattere=cognome.charAt(i);
    			if(Arrays.binarySearch (consonanti , carattere)>=0){
    				sb.append(carattere);
    				lettereCognome--;
    			}
    		}
    		if(lettereCognome>0){
    			for (int i=0;i<cognome.length() && lettereCognome>0 ; i++){
    				carattere = cognome.charAt (i);
    				if(Arrays.binarySearch (vocali , carattere)>=0){
    					sb.append(carattere);
    					lettereCognome--;
    				}
    			}
    		}
    		if (lettereCognome>0){
    			for(int i=0;i<lettereCognome;i++){
    				sb.append ('x');
    			}
    		}
    		//NOME
    		int lettereNome=3;
    		int lunghezzaNome = nome.length ();
    		if(numeroConsonanti (nome)>=4){
    			int successione=1;
    			for(int i=0;i<nome.length() && lettereNome>0 ;i++){
    				if(Arrays.binarySearch (consonanti , nome.charAt (i))>=0){
    					if(successione!=2){
    						sb.append (nome.charAt(i));
    						lettereNome--;
    						successione++;
    					}else{
    						successione++;
    					}
    				}
    			}
    		}else{
    			for(int i=0;i<nome.length() && lettereNome>0;i++){
    				if(Arrays.binarySearch (consonanti , nome.charAt (i))>=0){
    					sb.append(nome.charAt(i));
    					lettereNome--;
    				}
    			}
    			if(lettereNome>0){
    				for(int i=0;i<nome.length() && lettereNome>0 ;i++){
    					if(Arrays.binarySearch (vocali , nome.charAt(i))>=0){
    						sb.append(nome.charAt(i));
    						lettereNome--;
    					}
    				}
    				if(lettereNome>0){
    					for(int i=0;i<lettereNome;i++){
    						sb.append('x');
    					}
    				}
    			}
    		}
    		//DATA NASCITA E SESSO
    		sb.append ((anno+"").substring(2)); //ANNO
    		sb.append (lettereMesi [mese-1]); //MESE
    		String gg=null;
    		//SESSO E GIORNO
    		if(sesso=='f'){
    			gg=(giorno+40)+"";
    		}else if(sesso=='m'){
    			gg= (giorno<10) ? "0"+giorno : giorno+"";
    		}
    		sb.append(gg);
    		//COMUNE NASCITA
    		String s=read ("CODICICATASTALI.txt","UTF-8").replaceAll("\n","\t");
    		String [] array=s.split("\t");
    		String stringa=array [ricercaSequenziale (array , comuneNascita) + 1];
    		sb.append(stringa);
    		//CODICE DI CONTROLLO
    		int somma=0;
    		String temporanea=sb.toString();
    		for(int i=0;i<temporanea.length()-1;i++){
    			if(i%2==1){
    				//PARI
    				somma+=controlloPari [ricercaSequenziale (controlloCaratteri , temporanea.charAt(i))];
    			}else{
    				//DISPARI
    				somma+=controlloDispari [ricercaSequenziale (controlloCaratteri , temporanea.charAt(i))];
    			}
    		}
    		sb.append( alfabeto [somma%26]);
    		return sb.toString().toUpperCase();
    	}
    
    	private static int numeroConsonanti (String stringa) {
    		int numero=0;
    		for(int i=0;i<stringa.length();i++){
    			if(Arrays.binarySearch (consonanti , stringa.charAt(i))>=0){
    				numero++;
    			}
    		}
    		return numero;
    	}
    
    	private static int ricercaSequenziale (String [] arr , String chiave){
    		for(int i=0;i<arr.length;i++){
    			if(arr [i].equals(chiave)){
    				return i;
    			}
    		}
    		return -1;
    	}
    
    	private static int ricercaSequenziale (char [] arr , char chiave) {
    		for(int i=0;i<arr.length;i++){
    			if(arr [i]==chiave){
    				return i;
    			}
    		}
    		return -1;
    	}
    
    	public static String read(String fileName,String charSet){
    		BufferedReader buffRead=null;
    		StringBuilder strBuff=new StringBuilder();
    		try{
    			buffRead=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),charSet));
    			String str;
    			while((str=buffRead.readLine())!=null){
    				strBuff.append(str+"\r\n");
    			}
    			buffRead.close();
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		return strBuff.toString();
    	}
    
    	public static void main (String [] args) {
    		System.out.println(calcola ("rossi","antonio",25,05,1989,'m',"catanzaro"));
    		//DOVREBBE ESSERE RSSNTN89E25C352T
    		//MA INVECE STAMPA TSSNTN89E25C352
    	}
    }

    Fai finta che il file "CODICICATASTALI.txt" sia così composto (per semplificare la cosa):
    codice:
    catanzaro	c352
    IMPORTANTE: sarebbe catanzaro+tab+c352

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da zipangulu
    codice:
    String s=read ("CODICICATASTALI.txt","UTF-8").replaceAll("\n","\t");
    
    
    		System.out.println(calcola ("rossi","antonio",25,05,1989,'m',"catanzaro"));
    		//DOVREBBE ESSERE RSSNTN89E25C352T
    		//MA INVECE STAMPA TSSNTN89E25C352
    Fai finta che il file "CODICICATASTALI.txt" sia così composto (per semplificare la cosa):
    codice:
    catanzaro	c352
    IMPORTANTE: sarebbe catanzaro+tab+c352
    Direi che ho capito il problema. Sei su Windows, dicevi, giusto? Sui Windows il newline è CR+LF e tu fai un replaceAll solo del line-feed.
    Quindi hai ancora in mezzo ai piedi il carriage-return che non elimini.
    La "T" che dici che va all'inizio ... è perché nel file la riga di esempio finisce con c352<NEWLINE>
    Avendo in mezzo ai piedi il carriage-return, alla fine arrivi ad avere (prima del toUpperCase che non centra/sballa nulla) la stringa:

    rssntn89e25c352<CR>t

    Quando poi stampi su console, il CR fa ritornare all'inizio (non su nuova linea!) e vedi la "t" (poi tutto in maiuscolo ovviamente) all'inizio al posto della "r".

    Occhio a queste cose!

    P.S. e come vedi il StringBuilder è "innocente".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    Si hai ragione , era proprio quello l'errore...
    Per la cronaca ho risolto con:

    codice:
    String s=read ("CODICICATASTALI.txt","UTF-8").replaceAll("\r\n","\t");
    Ps. nel codice c'era un errore di distrazione nell'ultimo for per ricavare la cifra di controllo , diventa:

    codice:
    for(int i=0;i<temporanea.length();i++){
    prima ci stava <temporanea.length() - 1


    Grazie 1000 andbin , come sempre!

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Se vuoi renderlo portabile e non doverti, quindi, preoccupare di quale sia la sequenza di caratteri usata dal sistema per il terminatore di linea, usa la property


    codice:
    line.separator
    sostituendo nel tuo codice in questo modo:

    codice:
    replaceAll(System.getProperty("line.separator"), "\t");
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  10. #10
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    Ci stavo pensando anche io , bè quando possibile sempre meglio "universalizzare" la cosa
    Grazie!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.