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


468

Ho qualche difficoltà a compilare un programma C ++ che ho scritto.

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

Il programma è il seguente:

inserisci qui la descrizione dell'immagine

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

Sconcertato, ho provato g ++ 4.5.2, ma è stato altrettanto inutile:

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) dovesse funzionare, poiché è molto apprezzato per la sua conformità agli standard. Sfortunatamente, non mi ha nemmeno dato uno dei suoi bei messaggi di errore 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)

Ad essere sincero, non so davvero cosa significhi nessuno di questi messaggi di errore.

Molti altri programmi C ++ hanno file sorgente con estensione .cpp , quindi ho pensato che forse avrei dovuto 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 a usarlo per compilare il programma rinominato, è stato lanciato, stampato "84 avvisi e 20 errori generati". e ha fatto un sacco bip del 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ì rotti da non poter compilare questo semplice programma?

Risposte:


173

Nella norma, §2.1 / 1 specifica:

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

Il tuo compilatore non supporta quel formato (aka non può mapparlo al set di caratteri di base sorgente ), quindi non può passare a ulteriori fasi di elaborazione, da cui l'errore. È del tutto possibile che il compilatore supporti una mappatura dall'immagine al set di caratteri di base della sorgente, ma non è necessario.

Poiché questa mappatura è definita dall'implementazione, sarà necessario consultare la documentazione delle implementazioni per vedere i formati di file supportati. In genere, tutti i principali produttori di compilatori supportano file di testo (definiti canonicamente): 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:

La presente norma internazionale non specifica
- il meccanismo mediante il quale i programmi C vengono trasformati per l'uso da parte di 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 dei compilatori.


23
Penso che quella frase sia, nella migliore delle ipotesi, ambigua. Il dizionario Merriam-Webster afferma che il testo è le parole e la forma originali di un'opera scritta o stampata o di un'opera contenente tale testo . Questo file sorgente rientra chiaramente in tale definizione. Pensi che dovrei presentare un rapporto sui difetti con il Core Language Working Group?
James McNellis,

15
Oh; Ho completamente dimenticato di leggere tutti i documenti di riferimento. Penso che il paragrafo sia stato rimosso dal contesto, quindi andrò a leggere l'intera ISO / IEC 9899: 1990 e riporterò qui una volta che lo capirò completamente.
James McNellis,



211

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


44
Anche se non apprezzo che tu mi prenda in giro per la mia calligrafia, questo potrebbe essere il vero problema e spiegherebbe l'errore che ottengo quando provo a compilare il helloworld.cpp rinominato con Visual C ++: "errore fatale C1004: fine imprevista- file trovato "Riproverò e riporterò presto. Grazie!
James McNellis,

37
@James si assicura di disattivare tutte le ottimizzazioni png. semplifica il debug.
Wilhelmtell,

5
@James: "fine del file inattesa" significa quasi sicuramente che è il tuo a }causare il problema. Prova a concentrarsi sulla corrispondenza che con la{
Carson63000

156

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

110

Hai dimenticato di usare Comic Sans come carattere, ecco perché è un errore.


73
Sfortunatamente, questo è l'unico carattere supportato dalla mia mano. Sarebbe molto triste se non potessi programmare in C ++ per questo motivo. Pensi che Java supporterebbe questo carattere?
James McNellis,

8
Avrai bisogno del Comic Sans quando pensi di disegnare fumetti, quindi dovresti prendere seriamente in considerazione l'aggiornamento delle mani.
sharptooth,

8
Il C ++ richiede una formazione annuale in calligrafia. Se non hai tempo, prova Visual Basic o semplicemente il codice binario della macchina (devi solo ottenere gli 0 e gli 1 in quel momento).
Frank Osterfeld,

1
@Frank C ++ 0x §42.1 / 1 specifica "Tutte le stringhe devono essere in gotico".
Mateen Ulhaq,

75

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

Come sai: "Se un file di origine che non è vuoto non termina con un carattere di nuova riga, ... il comportamento non è definito".


16
Hmmm. Per fortuna questa regola ridicola è stata rimossa in C ++ 0x. Detto questo, come si fa a terminare un tale file con una nuova riga? Pensavo di aver lasciato spazio sufficiente alla fine del testo (se si evidenzia il file di origine, si dovrebbe vedere lo spazio aggiuntivo che ho lasciato). Grazie per la punta, però!
James McNellis,

8
Se non hai abbastanza spazio bianco, posso provare a compilarlo sul mio sistema. Ho quattro monitor in modo da poter provare a compilare da quello più a sinistra.
Tin Man

74

Questo programma è valido - Non riesco a trovare errori.

Suppongo che tu abbia un virus sulla tua macchina. Sarebbe meglio se si riformatta l'unità e si reinstalla il sistema operativo.

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

Odio i virus.


17
Sì, prova a installare Linux. Incolpo Windows per il tuo problema.
Raedwald,

62

Ho scoperto 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 quindi le persone che mi danno un monitor pulito mi chiamano i nomi ogni settimana.

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

Ecco perché assumo le persone intelligenti.


2
Un Wacom Cintiq è molto più appropriato per un manager. È costoso e ti fa sentire davvero importante. Tutti i grafici della tua azienda avranno uno stato molto più basso e quindi dovrebbero usare i monitor EGA. I bidelli dovrebbero usare i monitor CGA. I programmatori dovrebbero usare terminali monocromatici di seconda mano.
Steve314

7
Ho avuto un monitor "Life Like" per molto tempo. Era così realistico che avresti giurato che lo screensaver dei pesci nuotatori fosse reale, e il piccolo sommozzatore sembrava nuotare. Continuavo a bagnarmi il braccio cercando di estrarre il forziere dal fondo, era così reale. L'unico problema era che lo screen saver era sempre attivo e i rumori gorgoglianti realistici rendevano difficile ascoltare. Oh, e hanno detto che per manutenzione dovevo spargere roba nella parte superiore del monitor ogni giorno o lo screen saver avrebbe smesso di funzionare. Lo ha fatto una volta, e ragazzo, l'odore due giorni dopo era davvero realistico.
Tin Man

59

File format not recognizedDevi formattare correttamente il tuo file. Ciò significa utilizzare i colori e i caratteri giusti per il tuo codice. Vedi le documentazioni specifiche per ciascun compilatore poiché questi colori variano tra i compilatori;)


14
Oh, questo tipo di senso ha ... Ho una scatola di 96 pastelli, quindi sono sicuro di avere il colore di primo piano corretto. Prenderò un po 'di carta da costruzione colorata domani e lo proverò su un altro colore di carta.
James McNellis,

3
Per sicurezza, è meglio procurarsi anche matite colorate e colori a base di olio. È risaputo che C ++ è pensato per essere un linguaggio molto difficile da formattare correttamente.
helloworld922,

Sì, e non dimenticare di usare l'indicatore di evidenziazione.
sharptooth,

6
@sharptooth - l'evidenziazione della sintassi è una funzione IDE - non sei fatto per farlo a mano. Quindi assicurati di avere un braccio robotico con quel marcatore di evidenziazione.
Steve314

56

Hai dimenticato il pre-processore. Prova questo:

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

8
Oh! Pensavo che il preprocessore fosse incluso nel compilatore! Proverò a trovare un preprocessore che funzioni sul mio laptop Windows.
James McNellis,

3
@James McNellis: Il preprocessore non è un programma, è una cosa hardware che sembra un marcatore di evidenziazione: lo sposti sul testo e viene preelaborato.
sharptooth,

49

Hai scritto a mano il programma e poi lo hai scannerizzato sul computer? Questo è ciò che è implicato da "helloworld.png". In tal caso, è necessario essere consapevoli del fatto che lo standard C ++ (anche nella sua ultima edizione) non richiede la presenza del riconoscimento ottico dei caratteri e, sfortunatamente, non è incluso come funzionalità opzionale in nessun compilatore corrente.

Si consiglia di trasporre la grafica in un formato testuale. È possibile utilizzare qualsiasi editor di testo semplice; l'uso di un elaboratore di testi, sebbene in grado di generare una stampa piuttosto, molto probabilmente comporterà lo stesso errore che si ottiene durante il tentativo di scansione.

Se sei veramente avventuroso, puoi provare a scrivere il tuo codice in un elaboratore di testi. Stampalo, preferibilmente usando un font come OCR-A . Quindi, prendi la tua stampa ed esegui nuovamente la scansione. 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 molti compilatori standard.

Attenzione, tuttavia, al grande costo della carta che ciò comporta durante la fase di debug.


Il dilemma di pollo e uova: è possibile scrivere codice C ++ per un software OCR e compilarlo senza un OCR?
jweyrich,

5
Bene, duh, usi l'assemblaggio per l'OCR originale.
Kevin Lacquement

@jweyrich - Penso che dovrai prima avviare il tuo C ++ / OCR con la tua toolchain asm / OCR.
Michael Burr,


46

Disegna l'inclusione di seguito per compilarla:

#include <ChuckNorris>

Ho sentito che può compilare errori di sintassi ...


46
Personalmente preferisco #include <JonSkeet>.
Icode4food

40

Sfortunatamente, hai selezionato tre compilatori che supportano tutti 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 è in realtà. Ora, potresti usare mezzi non standard. Ad esempio, il compilatore di Visual Studio accetta gli argomenti della riga di comando / TC e / TP , oppure è possibile utilizzare l'opzione "Compila come: C ++" nel file di progetto. GCC e CLang hanno i loro meccanismi, che non conosco.

Pertanto, raccomanderei invece di utilizzare il metodo standard per dire al compilatore che il codice seguente è in C ++. Come hai scoperto ormai, i compilatori C ++ sono molto esigenti su ciò che accettano. Pertanto, il modo standard per identificare il C ++ è attraverso l'intimidazione che i programmatori aggiungono al loro codice C ++. Ad esempio, la seguente riga chiarirà al compilatore che ciò che segue è C ++ (e sarebbe meglio compilarlo senza lamentele).

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

10
Ho pensato che #pragmafosse il modo corretto di "ottenere un messaggio" per il compilatore?
Lev Bishop

33

Prova questo:

Vedi il dinosauro nella navetta spaziale?


4
Penso che ci sia un refuso - dovrebbe essere endl(L) non end1(uno). Ma +1 ben fatto!
Rup

44
Lo sto fissando da tre ore ma non riesco ancora a vedere un dinosauro o la navetta spaziale. :-(
oosterwal

32

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


27

L'OCR afferma:

N lml_e <loJ+_e__}

.lnt Mk.,n ( ln+ _rSC Lhc_yh )
h_S_
_l

s_l . co__ <, " H llo uo/_d ! '` << s l . ena_ .
TP__rn _ |
_|

Il che è dannatamente buono, per essere onesti.


4
Caspita, l'OCR è migliorato da quando ho provato a scansionare la mia calligrafia (ho passato ore a scriverla direttamente).
James P.

40
Penso che dobbiamo aggiungere un tag Perl.
Salterio

26

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

Ovviamente, dovresti formattare il tuo disco rigido.

Davvero, questi errori non sono così difficili da leggere.


20

Ho convertito il tuo programma da PNG in ASCII, ma non è stato ancora compilato. Per tua informazione, ho provato con la larghezza della riga 100 e 250 caratteri, ma entrambi producono risultati comparabili.

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

8
Probabilmente è meglio usare 80 o anche 72 colonne , invece
Tobias Kienzler

16

Il primo problema è che stai cercando di restituire un valore errato alla fine della funzione principale. Lo standard C ++ stabilisce che il tipo restituito da main () sia 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 file determina quale tipo di compilazione viene 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 una lettera maiuscola C.

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


3
Avevo un professore a ritroso quando chi si toglieva i compiti o gli esami se mettessi una barra attraverso una cifra zero poiché zero non è l'insieme nullo. Gradirebbe questa risposta.
Michael Burr,

15

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


13

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


L'ultima volta che ho sentito C ++ non specifica che i programmi devono essere scritti in ASCII, UTF-8 o altro.
Adrian Ratnapala,

8

Stai cercando di compilare un'immagine.

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


23
Controlla la data sul tuo PC.
James P.

14
Ahah, ma alla fine ne ho trovato uno facile a cui potevo rispondere!
Cody Grey

10
Questo è sciocco. Sappiamo tutti che il compilatore ottimizzerebbe lo spazio bianco, lasciando solo uno spazio nero fortemente compresso, che è tutto uno e comprimerebbe fino a un binario 1 che verrebbe restituito come errore. Il codice doveva essere scritto usando il white-out che si sarebbe compilato su 0 e non avrebbe restituito un errore.
Tin Man,

7

È necessario specificare la precisione dell'output preceduta da due punti immediatamente prima del controvento di chiusura finale . Poiché l'output non è numerico, la precisione è zero, quindi è necessario questo-

: 0}


5

Inserisci :

using namespace std;

subito dopo includere: P: D


5
Preferisco scrivere stdsempre. Mi ricorda di non averne uno.
Mateen Ulhaq,


5

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

Saluti,


5

Prova a cambiare l'interfaccia di input. C ++ prevede che una tastiera sia collegata al computer, non a uno scanner. Qui potrebbero esserci problemi di conflitto periferico. Non ho verificato lo standard ISO se l'interfaccia di input da tastiera è obbligatoria, ma questo è vero per tutti i compilatori che abbia 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.


5

Potresti provare diversi colori per le parentesi, forse un po 'di verde o rosso sarebbe d'aiuto? Penso che il tuo compilatore non possa riconoscere l'inchiostro nero: P


5

Sono l'unico che non è in grado di riconoscere il personaggio tra 'return' e il punto e virgola? Potrebbe essere!


4
È una lettera maiuscola O con una linea speciale che chiamiamo "diametro", che dice al compilatore di usare l'algoritmo del cerchio centrale, ovviamente. Penso che dovresti controllare gli occhi.
Mateen Ulhaq,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.