Perché questo programma è erroneamente rifiutato da tre compilatori C ++?

Sto avendo qualche difficoltà nel compilare un programma C ++ che ho scritto.

Questo programma è molto semplice e, per quanto ne so, è conforms a tutte le regole stabilite nello standard C ++. Ho letto per intero la ISO / IEC 14882: 2003 due volte per essere sicuro.

Il programma è il seguente:

inserisci la descrizione dell'immagine qui

Ecco l’output che ho ricevuto durante il tentativo di compilare questo programma con Visual C ++ 2010:

c:\dev>cl /nologo helloworld.png cl : Command line warning D9024 : unrecognized source file type 'helloworld.png', object file assumed helloworld.png : fatal error LNK1107: invalid or corrupt file: cannot read at 0x5172 

Abbattuto, ho provato g ++ 4.5.2, ma non è stato altrettanto utile:

 c:\dev>g++ helloworld.png helloworld.png: file not recognized: File format not recognized collect2: ld returned 1 exit status 

Ho pensato che Clang (versione 3.0 tronco 127530) deve funzionare, dal momento che è molto apprezzato per la sua conformità agli standard. Sfortunatamente, non mi ha nemmeno dato uno dei suoi messaggi di errore belli, evidenziati:

 c:\dev>clang++ helloworld.png helloworld.png: file not recognized: File format not recognized collect2: ld returned 1 exit status clang++: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation) 

Per essere onesti, non so davvero cosa significhi uno di questi messaggi di errore.

Molti altri programmi C ++ hanno file sorgente con estensione .cpp , quindi ho pensato che forse dovevo rinominare il mio file. Ho cambiato il suo nome in helloworld.cpp , ma questo non ha aiutato. Penso che ci sia un bug molto grave in Clang perché quando ho provato ad usarlo per compilare il programma rinominato, è stato stampato, “84 avvisi e 20 errori generati”. e ho fatto molto rumore al mio computer!

Cosa ho fatto di sbagliato qui? Ho perso qualche parte critica dello standard C ++? O tutti e tre i compilatori sono davvero così distrutti da non poter compilare questo semplice programma?

Nello standard, §2.1 / 1 specifica:

I caratteri del file di origine fisico vengono mappati, in modo definito dall’implementazione, al set di caratteri di base dell’origine (introducendo i caratteri di nuova riga per gli indicatori di fine riga) se necessario.

Il tuo compilatore non supporta quel formato (alias non può mapparlo al set di caratteri di base dell’origine ), quindi non può spostarsi in ulteriori fasi di elaborazione, quindi l’errore. È del tutto ansible che il tuo compilatore supporti una mapping dall’immagine al set di caratteri sorgente di base, ma non è necessario.

Poiché questa mapping è definita dall’implementazione, è necessario consultare la documentazione delle implementazioni per vedere i formati di file che supporta. In genere, tutti i principali produttori di compilatori supportano (canonicamente definiti) file di testo: qualsiasi file prodotto da un editor di testo, in genere una serie di caratteri.


Si noti che lo standard C ++ si basa sullo standard C (§1.1 / 2), e lo standard C (99) dice, in §1.2:

Questo standard internazionale non specifica
– il meccanismo mediante il quale i programmi C vengono trasformati per essere utilizzati da un sistema di elaborazione dati;
– il meccanismo mediante il quale i programmi C sono invocati per essere utilizzati da un sistema di elaborazione dati;
– il meccanismo mediante il quale i dati di input vengono trasformati per essere utilizzati da un programma C;

Quindi, ancora una volta, il trattamento dei file sorgente è qualcosa che devi trovare nella documentazione del tuo compilatore.

Originario di Overv @ reddit .

Prova in questo modo:

inserisci la descrizione dell'immagine qui

I tuoi < e > , ( e ) , { e } non sembrano corrispondere molto bene; Prova a disegnarli meglio.

Potresti provare il seguente script python. Si noti che è necessario installare PIL e pytesser .

 from pytesser import * image = Image.open('helloworld.png') # Open image object using PIL print image_to_string(image) # Run tesseract.exe on image 

Per usarlo, fai:

 python script.py > helloworld.cpp; g++ helloworld.cpp 

Hai dimenticato di usare Comic Sans come font, ecco perché il suo errore.

Non riesco a vedere una nuova riga dopo l’ultima parentesi.

Come sai: “Se un file sorgente che non è vuoto non termina con un carattere di nuova riga, … il comportamento non è definito”.

Questo programma è valido – Non riesco a trovare errori.

Immagino tu abbia un virus sulla tua macchina. Sarebbe meglio se riformattare l’unità e reinstallare il sistema operativo.

Facci sapere come funziona, o se hai bisogno di aiuto con la reinstallazione.

Odio i virus.

Ho trovato che aiuta a non scrivere il mio codice sul vetro del mio monitor con un pennarello magico, anche se sembra bello quando è davvero nero. Lo schermo si riempie troppo velocemente e poi le persone che mi danno un monitor pulito mi chiamano nomi ogni settimana.

Un paio di miei impiegati (sono un manager) stanno cercando di comprarmi uno di quei computer rossi con le manopole. Hanno detto che non avrò bisogno di marcatori e posso pulire lo schermo da solo quando è pieno, ma devo stare attento a scuoterlo. Supponevo che fosse delicato in quel modo.

Ecco perché assumo le persone intelligenti.

File format not recognized È necessario formattare correttamente il file. Ciò significa utilizzare i colors e i caratteri giusti per il tuo codice. Vedi le documentazioni specifiche per ogni compilatore in quanto questi colors variano tra compilatore;)

Hai dimenticato il pre-processore. Prova questo:

 pngtopnm helloworld.png | ocrad | g++ -x 'c++' - 

Hai scritto a mano il programma e poi lo hai scansionato nel computer? Questo è ciò che è implicito da “helloworld.png”. In tal caso, è necessario essere consapevoli che lo standard C ++ (anche nella sua ultima versione) non richiede la presenza del riconoscimento ottico dei caratteri, e sfortunatamente non è incluso come caratteristica opzionale in nessun compilatore corrente.

Potresti considerare di trasporre la grafica in un formato testuale. È ansible utilizzare qualsiasi editor di testo normale; l’uso di un elaboratore di testi, pur essendo in grado di generare una stampa abbastanza, causerà molto probabilmente lo stesso errore che si ottiene durante il tentativo di scansione.

Se sei veramente avventuroso, puoi provare a scrivere il tuo codice in un word processor. Stampalo, preferibilmente usando un font come OCR-A . Quindi, eseguire la stampa e digitalizzarla nuovamente. La scansione può quindi essere eseguita attraverso un pacchetto OCR di terze parti per generare un modulo di testo. Il modulo di testo può quindi essere compilato utilizzando uno dei tanti compilatori standard.

Attenzione, tuttavia, all’enorme costo della carta che questo incorrerà durante la fase di debugging.

Disegna l’include qui sotto per renderlo compilato:

 #include  

Ho sentito che può compilare errori di syntax …

Sfortunatamente, hai selezionato tre compilatori che supportano più lingue, non solo C ++. Devono tutti indovinare il linguaggio di programmazione che hai usato. Come probabilmente già saprai, il formato PNG è adatto a tutti i linguaggi di programmazione, non solo al C ++.

Di solito il compilatore può capire la lingua stessa. Ad esempio, se il PNG è ovviamente disegnato con i pastelli, il compilatore saprà che contiene Visual Basic. Se sembra disegnato con una matita meccanica, è facile riconoscere l’ingegnere al lavoro, scrivendo il codice FORTRAN.

Anche questo secondo passaggio non aiuta il compilatore, in questo caso. C e C ++ sembrano troppo simili, fino al #include . Pertanto, è necessario aiutare il compilatore a decidere quale lingua sia realmente. Ora, potresti usare mezzi non standard. Ad esempio, il compilatore di Visual Studio accetta gli argomenti della riga di comando / TC e / TP , oppure è ansible utilizzare l’opzione “Compila come: C ++” nel file di progetto. GCC e CLang hanno i loro meccanismi, che non conosco.

Pertanto, consiglierei di usare il metodo standard per dire al tuo compilatore che il codice che segue è in C ++. Come hai già scoperto, i compilatori C ++ sono molto esigenti su ciò che accettano. Quindi il modo standard per identificare C ++ è che i programmatori di intimidazione aggiungono al loro codice C ++. Ad esempio, la seguente riga chiarirà al compilatore che quanto segue è C ++ (e che sarebbe meglio compilarlo senza lamentele).

 // To the compiler: I know where you are installed. No funny games, capice? 

Il tuo compilatore è impostato in modalità esperto ?! Se sì, non dovrebbe essere compilato. I compilatori moderni sono stanchi di “Hello World!”

Prova questo:

Vedi il dinosauro nella navetta spaziale?

L’OCR dice:

 N lml_ e  

Il che è dannatamente buono, per essere onesti.

helloworld.png: file non riconosciuto: formato file non riconosciuto

Ovviamente, dovresti formattare il tuo disco rigido.

In realtà, questi errori non sono così difficili da leggere.

Ho convertito il tuo programma da PNG in ASCII, ma non è ancora compilato. Per vostra informazione, ho provato con una larghezza della linea di 100 e 250 caratteri, ma entrambi producono risultati comparabili.

  ` ` . `. ` ... +:: ..-.. --.:`:. `-` .....:`../--`.. `- ` ` ```` ` ` `` .` `` .` `. `` . -``- .. .`--`:` :::.-``-. : ``.-`- `-.-`:.-` :-`/.-..` ` `-..`...- : .` ` ` ` .` ````:`` - ` ``-.` ` `- .. `` . ` .`. ` ` `. ` . . ` . ` . . .` .` ` ` `` ` ` `:`.`:` ` -..-`.`- .-`-. /.-/.-`.-. -...-..`- :``` `-`-` :`..`-` ` :`.`:`- ` `` ` ```. `` ```` ` ` ` ` ` ` ` . : -...`.- .` .:/ ` - ` `` . -` ` 

Il primo problema è che si sta tentando di restituire un valore errato alla fine della funzione principale. Lo standard C ++ stabilisce che il tipo restituito da main () è int, ma invece si sta tentando di restituire il set vuoto.

L’altro problema è – almeno con g ++ – che il compilatore deduce la lingua utilizzata dal suffisso del file. Da g ++ (1):

Per ogni dato file di input, il suffisso del nome del file determina il tipo di compilazione eseguita:

file.cc file.cp file.cxx file.cpp file.CPP file.c ++ file.C

Codice sorgente C ++ che deve essere preelaborato. Nota che in .cxx, le ultime due lettere devono essere entrambe letteralmente x. Allo stesso modo, .C si riferisce a un capitale letterale C.

La soluzione di questi dovrebbe lasciarti con un’applicazione Hello World pienamente funzionante, come si può vedere dalla demo qui .

Il tuo font fa schifo, come dovrebbe mai un parser essere in grado di leggerlo? Segui un corso di calligrafia.

I tuoi compilatori si aspettano ASCII , ma quel programma è ovviamente scritto usando EBCDIC .

Stai cercando di compilare un’immagine.

Scrivi quello che hai scritto a mano in un documento chiamato main.cpp, esegui quel file attraverso il tuo compilatore, quindi esegui il file di output.

È necessario specificare la precisione dell’output preceduta da due punti immediatamente prima della parentesi finale di chiusura . Poiché l’output non è numerico, la precisione è zero, quindi è necessario-

: 0}

Inserisci :

 using namespace std; 

subito dopo includi: P: D

Sembra che il tuo compilatore non supporti i file in tale codifica hmm … Prova a convertirlo in ASCII.

Il problema sta nella definizione della syntax, prova a usare righello e compasso per una descrizione più classica!

Saluti,

Prova a cambiare l’interfaccia di input. C ++ si aspetta che una tastiera sia collegata al computer, non a uno scanner. Potrebbero esserci problemi di conflitto con le periferiche qui. Non ho controllato lo standard ISO se l’interfaccia di input da tastiera è obbligatoria, ma questo è vero per tutti i compilatori che ho mai usato. Ma forse l’input dello scanner è ora disponibile in C99, e in questo caso il tuo programma dovrebbe davvero funzionare. Altrimenti dovrai aspettare la prossima versione standard e l’aggiornamento dei compilatori.

Potresti provare colors diversi per parentesi, forse un po ‘di verde o rosso ti aiuterebbe? Penso che il tuo compilatore non possa riconoscere l’inchiostro nero: P

Sono l’unico a non riconoscere il carattere tra “ritorno” e punto e virgola? Potrebbe essere così!