Soluzione 4.2

Ecco una possibile soluzione. Notare che abbiamo scritto un metodo ausiliario static che realizza la conversione di una riga di parole nel formato desiderato. Notare anche il modo in cui sono state gestite le eccezioni.
Per quanto riguarda l'approfondimento (gestione delle parole separate dagli apostrofi), notare che abbiamo usato il metodo setDelimiter della classe Scanner per ridefinire i caratteri delimitatori. L'esercizio e` poi ulteriormente complicato dal fatto che in questo caso vogliamo usare il segno di apostrofo come carattere delimitatore ma non vogliamo "saltarlo" nella lettura, ovvero vogliamo che anche l'apostrofo venga stampato.
I piu` interessati possono studiare la classe StringTokenizer per una soluzione alternativa al problema (notate pero` che l'uso di StringTokenizer e` sconsigliato a partire da Java 5.0, dal momento che Scanner offre -quasi- tutte le stesse funzionalita`).
import java.util.Scanner;
import java.io.*;

public class CapsCopier
{
    public static void main(String[] args)
    {
    Scanner console = new Scanner(System.in);

    Scanner infile=null;
    boolean done = false;
    while (!done)
    {
        try
        {
            System.out.println("File input:");
            String infilename = console.nextLine();
            infile = new Scanner(new FileReader(infilename));
            done = true;
        }
        catch (FileNotFoundException e)
        {   System.out.println("Il file specificato non esiste!"); }
    }

    System.out.println("File output:");
    String outfilename = console.nextLine();
    PrintWriter outfile = null;
    try
    {   outfile = new PrintWriter(outfilename); }
    catch (FileNotFoundException e)
    {
        System.out.println("Non riesco ad aprire il file in scrittura");
        System.exit(1);
    }

    while (infile.hasNextLine())
        {
            outfile.println(toInitUpCase(infile.nextLine()));
        }
    infile.close();
    outfile.close();
    }

    /*
        Metodo ausiliario che elabora una riga di testo: 
        ciascuna parola della riga viene modificata in modo
        da avere la prima lettera maiuscola e le seguenti minuscole. 
    */
    private static String toInitUpCase(String line)
    {
    Scanner stok = new Scanner(line);
    String templine = "";
    while(stok.hasNext())
        {
        String token = stok.next();
        String neword = token.substring(0,1).toUpperCase();
        if (token.length() > 1)
            neword += token.substring(1).toLowerCase();
        templine += neword + " "; //ricordiamoci di reinserire spazi tra parole
        }
    //rimuoviamo l'ultimo spazio inserito alla fine della riga
    templine = templine.substring(0,templine.length()-1); 

    //Ora templine contiene le parole formattate come richiesto dall'esercizio

    //APPROFONDIMENTO: gestiamo l'eventuale presenza
    //di parole separate da apostrofi in templine    

    stok = new Scanner(templine);
    //Attenzione: cosa fa il metodo useDelimiter? Consultare la documentazione
    stok.useDelimiter("'");
    String newline = "";
    while(stok.hasNext())
        {
        String token = stok.next();
        String neword = token.substring(0,1).toUpperCase();
        if (token.length() > 1)
            neword += token.substring(1);
        newline += neword + "'";//ricordiamoci di reinserire ' tra le parole
        }
    //rimuoviamo l'ultimo ' inserito alla fine della riga
    newline = newline.substring(0,newline.length()-1);

    return newline;
    }
}