Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1

    [C++] Passare come argomento array di tipi char a una funzione

    Salve a tutti, sono nuovo nel forum, molti anni fa avevo imparato i fondamenti del linguaggio Visual Basic, e dopo una lunga pausa ho deciso di imparare nuovamente a programmare, questa volta con il pi� versatile C++. Sto utilizzando l'apposita guida di questo sito, aggiungendo e modificando codice nella classica applicazione (console) HelloWorld. La parte di codice in questione � (Origine.cpp):
    codice:
    #include <iostream>
    #include <Windows.h>
    #include <winnt.h>

    class Ciao
    {
    public:
    void saludandonio()
    {
    std::cout << "Saluda Andonio!" << std::endl;
    }

    LPSTR stampa_oem(char tds[]) //il programma viene eseguito, ma non viene stampata correttamente la �, viene stampata una U accentata
    {
    CharToOemBuffA(tds, tds, sizeof(tds));
    std::cout << tds;
    return tds;
    }
    };

    int main()
    {
    Ciao ciao;
    ciao.saludandonio();
    system("pause");

    char carattere[] = "perch����";
    std::cout << carattere << std::endl; //stampa errata con simboli strani
    ciao.stampa_oem(carattere); //stampa ancora errata
    std::cout << std::endl;

    CharToOemBuffA(carattere, carattere, sizeof(carattere)); //Effettua una conversione in-place della stringa al codepage OEM.
    std::cout << carattere << std::endl; //stampa corretta

    system("pause");
    }
    Ho fatto numerose prove con tipi diversi da LPSTR, ciononostante non sono mai riuscito a ottenere la stampa corretta a console (che viene ottenuta solo con la chiamata "non nidificata" di CharToOEMBuffA). LPCSTR d� risultati analoghi, altri tipi come char generano errori di compilazione. anche il tentativo:
    codice:
    char stampa_oem[](char tds[])
    genera errori. Chiedo quindi quale tipo possa essere dichiarato per ottenere un output corretto dalla funzione stampa_oem.
    Utilizzo la versione gratuita di Visual Studio 2017 su Windows 10, grazie in anticipo a chi vorr� aiutarmi!

  2. #2
    Utente di HTML.it
    Registrato dal
    Aug 2016
    Messaggi
    16
    Ciao provo a risolvere il tuo problema al massimo delle mie conoscenze
    Innanzitutto ti sconsiglio di creare una classe per una sola funzione
    Meglio usare una funzione singola e richiamare all'occorrenza quella
    sintassi funzione

    codice:
    [tipo_ritornato nome (eventuali parametri){
             Istruzioni....
             eventuali return
    }
    Nel tuo caso si costruisce una funzione che ha come parametri un array di char e la dimensione dell'array considerando il fatto che la dimensione di un char sia quasi sempre di 1 byte

    void stampa(char scritta[],int grandezza); void perché stampa e basta

    all'interno della funzione con un ciclo for stampo ogni singolo carattere

    codice:
    for(int i=0;i<grandezza;i++) finché ho caratteri da stampare...
        cout<<scritta[i]; stampo l' i-esimo carattere
      cout<<endl;  va a capo dopo aver stampato tutto
    [

    Puoi utilizzare comandi come CharToOemBuffA(scitta,scritta,grandezza) includendo la windows.h per convertire eventuali lettere con accenti in formato Oem e cosi stampabili con cout

    Il codice cosi completo potrebbe essere
    codice:
    #include <iostream>
    #include <windows.h>
    
    void stampa(char scritta[],int grandezza); //prototipo
    
    using namespace std;
    
    
    
    int main(){
          char scritta[]={"Saluda Andonio!"}; //creo il mio array inizzializzandolo con la tua frase
          stampa(scritta,sizeof(scritta)); //richiamo la funzione
    }
    
    
    void stampa(char scritta[],int grandezza){ //funzione
          for(int i=0;i<grandezza;i++)
          cout<<scritta[i];
          cout<<endl;
    }
    Spero di esserti stato utile ! Ciao
    Ultima modifica di Gardo; 18-07-2017 a 22:43

  3. #3
    Quote Originariamente inviata da Gardo Visualizza il messaggio
    Ciao provo a risolvere il tuo problema al massimo delle mie conoscenze
    Innanzitutto ti sconsiglio di creare una classe per una sola funzione
    Meglio usare una funzione singola e richiamare all'occorrenza quella
    sintassi funzione

    codice:
    [tipo_ritornato nome (eventuali parametri){
             Istruzioni....
             eventuali return
    }
    Nel tuo caso si costruisce una funzione che ha come parametri un array di char e la dimensione dell'array considerando il fatto che la dimensione di un char sia quasi sempre di 1 byte

    void stampa(char scritta[],int grandezza); void perché stampa e basta

    all'interno della funzione con un ciclo for stampo ogni singolo carattere

    codice:
    for(int i=0;i<grandezza;i++) finché ho caratteri da stampare...
        cout<<scritta[i]; stampo l' i-esimo carattere
      cout<<endl;  va a capo dopo aver stampato tutto
    [

    Puoi utilizzare comandi come CharToOemBuffA(scitta,scritta,grandezza) includendo la windows.h per convertire eventuali lettere con accenti in formato Oem e cosi stampabili con cout

    Il codice cosi completo potrebbe essere
    codice:
    #include <iostream>
    #include <windows.h>
    
    void stampa(char scritta[],int grandezza); //prototipo
    
    using namespace std;
    
    
    
    int main(){
          char scritta[]={"Saluda Andonio!"}; //creo il mio array inizzializzandolo con la tua frase
          stampa(scritta,sizeof(scritta)); //richiamo la funzione
    }
    
    
    void stampa(char scritta[],int grandezza){ //funzione
          for(int i=0;i<grandezza;i++)
          cout<<scritta[i];
          cout<<endl;
    }
    Spero di esserti stato utile ! Ciao
    Ciao Gardo, ti ringrazio per la risposta, purtroppo il problema permane, ho provato ad eseguire questo codice:
    codice:
    #include <iostream>
    #include <windows.h>
    
    void stampa(char scritta[], int grandezza); //prototipo
    
    using namespace std;
    
    
    
    int main() {
        char scritta[] = { "Saluda Andonio!" }; //creo il mio array inizzializzandolo con la tua frase
        char strano[] = { "èéàòù perchééé" };
        stampa(scritta, sizeof(scritta)); //richiamo la funzione
        system("pause");
        stampa(strano, sizeof(strano));
        system("pause");
    }
    
    
    void stampa(char scritta[], int grandezza) { //funzione
        for (int i = 0; i<grandezza; i++)
            cout << scritta[i];
        cout << endl;
    }
    Ma l'output della console rimane errato, come da immagine allegata


    è possibile che ci sia qualche problema specificatamente nel mio PC per quanto riguarda le codifiche?

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Manca la conversione.
    codice:
    void stampa(const char scritta[], int grandezza); //prototipo
    
    using namespace std;
    
    int main() {
        const char scritta[] = { "Saluda Andonio!" }; //creo il mio array inizzializzandolo con la tua frase
        const char strano[] = { "èéàòù perchééé" };
        char res[4096] = { 0 }; // buffer di conversione
        CharToOemBuffA(strano, res, 4096); // conversione
        stampa(scritta, sizeof(scritta)); //richiamo la funzione
        stampa(res, strlen(res)); // solo i caratteri convertiti, non l'intero buffer
    }
    
    
    void stampa(const char scritta[], int grandezza) { //funzione
        for (int i = 0; i<grandezza; i++)
            cout << scritta[i];
        cout << endl;
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Manca la conversione.
    codice:
    void stampa(const char scritta[], int grandezza); //prototipo
    
    using namespace std;
    
    int main() {
        const char scritta[] = { "Saluda Andonio!" }; //creo il mio array inizzializzandolo con la tua frase
        const char strano[] = { "èéàòù perchééé" };
        char res[4096] = { 0 }; // buffer di conversione
        CharToOemBuffA(strano, res, 4096); // conversione
        stampa(scritta, sizeof(scritta)); //richiamo la funzione
        stampa(res, strlen(res)); // solo i caratteri convertiti, non l'intero buffer
    }
    
    
    void stampa(const char scritta[], int grandezza) { //funzione
        for (int i = 0; i<grandezza; i++)
            cout << scritta[i];
        cout << endl;
    }
    Ho finalmente risolto, mi hai dato l'ispirazione shodan ciò che volevo inizialmente fare era costruire una funzione che, ricevendo come parametro in input una stringa di caratteri di testo, effettuasse preventivamente una conversione e poi stampasse a console, il tutto "internamente", in maniera tale da chiamare all'occorrenza la funzione con il testo desiderato. Questo è il codice modificato, con la void stampa_converti che si comporta come volevo:
    codice:
    #include <iostream>
    #include <Windows.h>
    
    void stampa(const char scritta[], int grandezza); //prototipo
    void stampa_converti(const char strano[]);
    
    using namespace std;
    
    int main() {
        const char scritta[] = { "Saluda Andonio!" }; //creo il mio array inizzializzandolo con la tua frase
        const char strano[] = { "èéàòù perchééé" };
        char res[4096] = { 0 }; // buffer di conversione
        CharToOemBuffA(strano, res, 4096); // conversione
        stampa(scritta, sizeof(scritta)); //stampa il saluto (non convertito)
        stampa(res, strlen(res)); // stampa i caratteri convertiti, non l'intero buffer
        system("pause");
        stampa_converti(strano);
        system("pause");
    }
    
    
    void stampa(const char scritta[], int grandezza) { //funzione
        for (int i = 0; i<grandezza; i++)
            cout << scritta[i];
        cout << endl;
    }
    
    void stampa_converti(const char strano[]) {
        char res1[4096] = { 0 }; // buffer di conversione
        CharToOemBuffA(strano, res1, 4096);
        cout << res1 << endl;
    }
    A un primo sguardo, noto che nel mio codice iniziale, non utilizzavo il buffer di conversione, bensì riversavo tutto nella stringa iniziale (che perciò non era const), e non dichiaravo mai la dimensione della stringa. Erano questi mancati accorgimenti a causare il problema?

  6. #6
    Utente di HTML.it
    Registrato dal
    Aug 2016
    Messaggi
    16
    Scusate l'ignoranza ma non sarebbe bastato fare la funzione così ? :
    codice:
    void stampa(char scritta[],int grandezza){
      CharToOemBuffA(scritta,scritta,grandezza);
      for(int i=0;i<grandezza;i++)
        cout<<scritta[i];
      cout<<endl;
    }
    e per richiamarla basta
    codice:
    stampa(strano,sizeof(strano));

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il vero problema era qui:
    codice:
    CharToOemBuffA(tds, tds, sizeof(tds));
    tds è un puntatore e come tale la sua sizeof() è 4byte (32bit) o 8byte (64bit) per cui al massimo i caratteri convertiti erano quella quantità. Ricorda che un array passato a una funzione è convertito implicitamente in un puntatore al primo elemento.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  8. #8
    Utente di HTML.it
    Registrato dal
    Aug 2016
    Messaggi
    16
    Si ma io passo grandezza che è la dimensione in byte dell'array
    CharToOemBuffA(scritta,scritta,grandezza);
    Ultima modifica di Gardo; 19-07-2017 a 12:19

  9. #9
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Il vero problema era qui:
    codice:
    CharToOemBuffA(tds, tds, sizeof(tds));
    tds è un puntatore e come tale la sua sizeof() è 4byte (32bit) o 8byte (64bit) per cui al massimo i caratteri convertiti erano quella quantità. Ricorda che un array passato a una funzione è convertito implicitamente in un puntatore al primo elemento.
    Perciò la chiave di tutto il ragionamento, se ho capito bene, è imporre l'array di char strano[] come const, in maniera tale che la funzione riceva in ingresso proprio l'array intero e non il puntatore al primo elemento?

  10. #10
    Utente di HTML.it
    Registrato dal
    Aug 2016
    Messaggi
    16
    Allora tutte le volte che passi un array ad una funzione in verità passi solo la posizione del primo elemento anche se poni const (infatti puoi scrivere char scritta[] come char *scritta che sono equivalenti). La funzione a priori non conosce la dimensione del vettore e qui salta in gioco la seconda variabile passata che è grandezza ed equivale alla dimensione in byte dell'array.
    Se nel main scrivessi
    codice:
    const char scritta[]={"Saluda Andonio!"};
     cout<<sizeof(scritta);
    avrei come stampa 16 che sono i byte di scritta[]
    se invece dalla funzione anche se const scrivessi cout<<sizeof(array_passato) avrei come stampa 4 (32bit) o 8 (64bit) che sono la dimensione del puntatore come aveva detto shodan.
    Con questa funzione
    codice:
    void stampa(char scritta[],int grandezza){
      CharToOemBuffA(scritta,scritta,grandezza);
      for(int i=0;i<grandezza;i++)
        cout<<scritta[i];
      cout<<endl;
    }
    La funzione riceve il primo elemento del tuo array NON const perché poi dovrà essere modificato con CharToOemBuffA e sarebbe stato impossibile modificarlo se fosse stato definito const
    Ora scritta puntatore e strano[0] hanno lo stesso indirizzo, ciò che accade ad uno accade anche all'altro quindi anche l'array di partenza(strano[]) viene modificato alla chiamata di CharToOemBuffA. Il comando CharToOemBuffA prende l'array puntatore, lo converte conoscendo la sua dimensione (grandezza) e lo sovrascrive a quello iniziale.
    Puoi richiamare la funzione con qualsiasi array tu abbia dichiarato nel main
    codice:
    char scritta[]={"Saluda Andonio!"};
    char scritta2[]={"èéòàùì"};
    stampa(scritta,sizeof(scritta));
    stampa(scritta2,sizeof(scritta2));
    Spero di essere stato d'aiuto e di non aver scazzato qualcosa

Tag per questa discussione

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.