Pourquoi ce programme est-il rejeté par erreur par trois compilateurs C ++?


468

J'ai de la difficulté à compiler un programme C ++ que j'ai écrit.

Ce programme est très simple et, à ma connaissance, est conforme à toutes les règles énoncées dans la norme C ++. J'ai lu l'intégralité de l'ISO / IEC 14882: 2003 deux fois pour être sûr.

Le programme est le suivant:

entrez la description de l'image ici

Voici la sortie que j'ai reçue en essayant de compiler ce programme avec 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

Consterné, j'ai essayé g ++ 4.5.2, mais c'était tout aussi inutile:

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

J'ai pensé que Clang (version 3.0 trunk 127530) devait fonctionner, car il était très apprécié pour sa conformité aux normes. Malheureusement, il ne m'a même pas donné l'un de ses jolis messages d'erreur mis en évidence:

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)

Pour être honnête, je ne sais pas vraiment ce que signifient ces messages d'erreur.

De nombreux autres programmes C ++ ont des fichiers source avec une extension .cpp , donc j'ai pensé que j'avais peut-être besoin de renommer mon fichier. J'ai changé son nom en helloworld.cpp , mais cela n'a pas aidé. Je pense qu'il y a un bogue très grave dans Clang parce que lorsque j'ai essayé de l'utiliser pour compiler le programme renommé, il s'est retourné, imprimé "84 avertissements et 20 erreurs générées". et fait beaucoup biper mon ordinateur!

Qu'est-ce que j'ai fait de mal ici? Ai-je manqué une partie critique de la norme C ++? Ou les trois compilateurs sont-ils vraiment tellement cassés qu'ils ne peuvent pas compiler ce programme simple?

Réponses:


173

Dans la norme, le §2.1 / 1 précise:

Les caractères du fichier source physique sont mappés, d'une manière définie par l'implémentation, au jeu de caractères source de base (en introduisant des caractères de nouvelle ligne pour les indicateurs de fin de ligne) si nécessaire.

Votre compilateur ne prend pas en charge ce format (aka ne peut pas le mapper au jeu de caractères source de base ), il ne peut donc pas passer à des étapes de traitement ultérieures, d'où l'erreur. Il est tout à fait possible que votre compilateur prenne en charge un mappage de l'image au jeu de caractères source de base, mais ce n'est pas obligatoire.

Étant donné que ce mappage est défini par l'implémentation, vous devrez consulter la documentation de vos implémentations pour voir les formats de fichiers pris en charge. En règle générale, tous les principaux éditeurs de compilateurs prennent en charge les fichiers texte (définis de manière canonique): tout fichier produit par un éditeur de texte, généralement une série de caractères.


Notez que la norme C ++ est basée sur la norme C (§1.1 / 2), et la norme C (99) dit, au §1.2:

La présente Norme internationale ne spécifie pas
- le mécanisme par lequel les programmes C sont transformés pour être utilisés par un système informatique;
- le mécanisme par lequel les programmes C sont invoqués pour être utilisés par un système informatique;
- le mécanisme par lequel les données d'entrée sont transformées pour être utilisées par un programme C;

Donc, encore une fois, le traitement des fichiers source est quelque chose que vous devez trouver dans la documentation de votre compilateur.


23
Je pense que cette phrase est au mieux ambiguë. Le dictionnaire Merriam-Webster dit que le texte est les mots et la forme d'origine d'une œuvre écrite ou imprimée ou d' une œuvre contenant un tel texte . Ce fichier source correspond clairement à cette définition. Pensez-vous que je devrais déposer un rapport d'anomalie auprès du Core Language Working Group?
James McNellis

15
Oh; J'ai complètement oublié de lire tous les documents référencés. Je pense que ce paragraphe est sorti de son contexte, alors je vais lire l'intégralité de l'ISO / CEI 9899: 1990 et je reviendrai ici une fois que je l'aurai compris.
James McNellis



211

Votre <et >, (et ), {et }ne semblent pas très bien correspondre; Essayez de mieux les dessiner.


44
Bien que je n'apprécie pas que vous vous moquiez de mon écriture, cela pourrait être le vrai problème et expliquerait l'erreur que j'obtiens lorsque j'essaie de compiler le helloworld.cpp renommé avec Visual C ++: "Erreur fatale C1004: fin inattendue- fichier trouvé "Je réessayerai et je ferai un rapport bientôt. Merci!
James McNellis

37
@James veille à désactiver toutes les optimisations png. cela facilite le débogage.
wilhelmtell du

5
@James: "fin de fichier inattendue" signifie presque certainement que c'est votre }cause du problème. Essayez de vous concentrer sur la correspondance avec le{
Carson63000

156

Vous pouvez essayer le script python suivant. Notez que vous devez installer PIL et pytesser .

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

Pour l'utiliser, faites:

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

110

Vous avez oublié d'utiliser Comic Sans comme police, c'est pourquoi son erreur.


73
Malheureusement, c'est la seule police prise en charge par ma main. Ce serait très triste si je ne peux pas programmer en C ++ à cause de cela. Pensez-vous que Java prendrait en charge cette police?
James McNellis

8
De toute façon, vous aurez besoin de Comic Sans lorsque vous pensez à dessiner des bandes dessinées, vous devriez donc sérieusement envisager de vous améliorer.
sharptooth

8
Le C ++ nécessite une formation d'un an en calligraphie. Si vous n'avez pas le temps, essayez Visual Basic ou tout simplement le code machine binaire (il vous suffit alors d'obtenir les 0 et les 1).
Frank Osterfeld

1
@Frank C ++ 0x §42.1 / 1 spécifie "Toutes les chaînes doivent être en gothique."
Mateen Ulhaq

75

Je ne vois pas de nouvelle ligne après cette dernière accolade.

Comme vous le savez: "Si un fichier source qui n'est pas vide ne se termine pas par un caractère de nouvelle ligne, ... le comportement n'est pas défini".


16
Hmmm. Heureusement, cette règle ridicule a été supprimée en C ++ 0x. Cela dit, comment peut-on terminer un tel fichier avec une nouvelle ligne? Je pensais avoir laissé suffisamment de place à la fin du texte (si vous mettez en surbrillance le fichier source, vous devriez voir l'espace supplémentaire que j'ai laissé). Merci pour l'astuce!
James McNellis

8
Si vous n'avez pas assez d'espace, je peux essayer de le compiler sur mon système. J'ai quatre moniteurs afin que je puisse essayer de compiler à partir de mon plus à gauche.
The Tin Man

74

Ce programme est valide - je ne trouve aucune erreur.

Je suppose que vous avez un virus sur votre machine. Il serait préférable de reformater votre disque et de réinstaller le système d'exploitation.

Faites-nous savoir comment cela fonctionne, ou si vous avez besoin d'aide pour la réinstallation.

Je déteste les virus.


17
Oui, essayez d'installer Linux. Je blâme Windows pour votre problème.
Raedwald

62

J'ai trouvé qu'il est utile de ne pas écrire mon code sur la vitre de mon moniteur avec un marqueur magique, même s'il a l'air bien quand il est vraiment noir. L'écran se remplit trop vite et puis les gens qui me donnent un moniteur propre m'appellent chaque semaine.

Un couple de mes employés (je suis un directeur) intervient pour m'acheter un de ces ordinateurs avec les boutons. Ils ont dit que je n'aurais pas besoin de marqueurs et que je peux nettoyer l'écran moi-même quand il est plein mais je dois faire attention en le secouant. Je suppose que c'est délicat de cette façon.

C'est pourquoi j'engage des gens intelligents.


2
Un Wacom Cintiq est beaucoup plus approprié pour un manager. C'est cher et vous vous sentez vraiment important. Tous les graphistes de votre entreprise auront un statut bien inférieur et devraient donc utiliser des moniteurs EGA. Les concierges devraient utiliser des moniteurs CGA. Les programmeurs doivent utiliser des terminaux monochromes d'occasion.
Steve314

7
J'avais un moniteur "Life Like" depuis longtemps. C'était tellement réaliste que vous jureriez que l'économiseur d'écran de poissons nageurs était réel, et le petit plongeur avait l'air de nager. Je n'arrêtais pas de mouiller mon bras en essayant de sortir le coffre au trésor du fond, c'était tellement réel. Le seul problème était que l'économiseur d'écran était toujours activé et les bruits de bouillonnement réalistes rendaient difficile à entendre. Oh, et ils ont dit pour la maintenance que je devais arroser quotidiennement des choses dans le haut du moniteur, sinon l'économiseur d'écran cesserait de fonctionner. Il l'a fait une fois, et mon garçon, l'odeur deux jours plus tard était vraiment réaliste.
The Tin Man

59

File format not recognizedVous devez formater correctement votre fichier. Cela signifie utiliser les bonnes couleurs et polices pour votre code. Voir les documentations spécifiques à chaque compilateur car ces couleurs varient d'un compilateur à l'autre;)


14
Oh, ce genre de sens ... J'ai une boîte de 96 crayons, donc je suis sûr que j'ai la bonne couleur de premier plan. Je vais prendre du papier de construction coloré demain et l'essayer sur une autre couleur de papier.
James McNellis

3
Juste pour être sûr, vous feriez mieux d'obtenir des crayons de couleur et de la peinture à l'huile. C'est un fait bien connu que C ++ est censé être un langage très difficile à formater correctement.
helloworld922

Oui, et n'oubliez pas d'utiliser le marqueur de surbrillance.
sharptooth

6
@sharptooth - la coloration syntaxique est une fonctionnalité IDE - vous n'êtes pas censé le faire à la main. Assurez-vous donc d'avoir un bras de robot pour aller avec ce marqueur de surbrillance.
Steve314

56

Vous avez oublié le pré-processeur. Essaye ça:

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

8
Oh! Je pensais que le préprocesseur était inclus avec le compilateur! Je vais essayer de trouver un préprocesseur qui fonctionne sur mon ordinateur portable Windows.
James McNellis

3
@James McNellis: Le préprocesseur n'est pas un programme, c'est une chose matérielle qui ressemble à un marqueur de surbrillance - vous le déplacez sur votre texte et il est prétraité.
sharptooth

49

Avez-vous écrit le programme à la main puis numérisé dans l'ordinateur? C'est ce que sous-entend "helloworld.png". Si tel est le cas, vous devez être conscient que le standard C ++ (même dans sa dernière édition) ne nécessite pas la présence de reconnaissance optique de caractères, et malheureusement il n'est inclus comme fonctionnalité optionnelle dans aucun compilateur actuel.

Vous voudrez peut-être envisager de transposer les graphiques dans un format textuel. Tout éditeur de texte brut peut être utilisé; l'utilisation d'un traitement de texte, bien que capable de générer une jolie impression, entraînera très probablement la même erreur que vous obtenez en essayant de numériser.

Si vous êtes vraiment aventureux, vous pouvez essayer d'écrire votre code dans un traitement de texte. Imprimez-le, de préférence en utilisant une police comme OCR-A . Ensuite, prenez votre impression et numérisez-la à nouveau. La numérisation peut ensuite être exécutée via un package OCR tiers pour générer un formulaire texte. Le formulaire texte peut ensuite être compilé à l'aide de l'un des nombreux compilateurs standard.

Attention cependant au coût élevé du papier que cela entraînera lors de la phase de débogage.


Le dilemme du poulet et des œufs: est-il possible d'écrire du code C ++ pour un logiciel d'OCR et de le compiler sans OCR?
jweyrich

5
Eh bien, vous utilisez l'assemblage pour l'OCR d'origine.
Kevin Lacquement le

@jweyrich - Je pense que vous devrez d'abord démarrer votre C ++ / OCR avec votre chaîne d'outils asm / OCR.
Michael Burr


46

Dessinez l'inclusion ci-dessous pour le compiler:

#include <ChuckNorris>

J'entends qu'il peut compiler des erreurs de syntaxe ...


46
Personnellement, je préfère #include <JonSkeet>.
Icode4food

40

Malheureusement, vous avez sélectionné trois compilateurs qui prennent tous en charge plusieurs langues, pas seulement C ++. Ils doivent tous deviner le langage de programmation que vous avez utilisé. Comme vous le savez probablement déjà, le format PNG convient à tous les langages de programmation, pas seulement au C ++.

Habituellement, le compilateur peut comprendre le langage lui-même. Par exemple, si le PNG est évidemment dessiné avec des crayons, le compilateur saura qu'il contient Visual Basic. Si on dirait qu'il est dessiné avec un crayon mécanique, il est facile de reconnaître l'ingénieur au travail, en écrivant le code FORTRAN.

Cette deuxième étape n'aide pas non plus le compilateur, dans ce cas. C et C ++ semblent tout simplement trop similaires, jusqu'à la #include. Par conséquent, vous devez aider le compilateur à décider de quelle langue il s'agit réellement. Maintenant, vous pouvez utiliser des moyens non standard. Par exemple, le compilateur Visual Studio accepte les arguments de ligne de commande / TC et / TP , ou vous pouvez utiliser l'option "Compiler en tant que: C ++" dans le fichier de projet. GCC et CLang ont leurs propres mécanismes, que je ne connais pas.

Par conséquent, je recommanderais d'utiliser la méthode standard à la place pour indiquer à votre compilateur que le code suivant est en C ++. Comme vous l'avez découvert maintenant, les compilateurs C ++ sont très pointilleux sur ce qu'ils acceptent. Par conséquent, la façon standard d'identifier C ++ est par les programmeurs d'intimidation ajouter à leur code C ++. Par exemple, la ligne suivante clarifiera à votre compilateur que ce qui suit est C ++ (et il ferait mieux de le compiler sans se plaindre).

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

10
Je pensais que #pragmac'était la bonne façon de "faire passer un message" au compilateur?
Lev Bishop

33

Essaye celui-là:

Voyez-vous le dinosaure dans la navette spatiale?


4
Je pense qu'il y a une faute de frappe - ça devrait être endl(L) pas end1(un). Mais +1 bien fait!
Rup

44
Je le regarde depuis trois heures, mais je ne vois toujours pas de dinosaure ni de navette spatiale. :-(
oosterwal

32

Votre compilateur est-il réglé en mode expert?! Si oui, il ne devrait pas être compilé. Les compilateurs modernes en ont assez de "Hello World!"


27

OCR dit:

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 _ |
_|

Ce qui est sacrément bon, pour être juste.


4
Wow, l'OCR s'est amélioré depuis que j'ai essayé de scanner mon écriture (j'ai passé des heures à l'écrire aussi).
James P.

40
Je pense que nous devons ajouter une balise Perl.
MSalters

26

helloworld.png: fichier non reconnu: format de fichier non reconnu

Évidemment, vous devez formater votre disque dur.

Vraiment, ces erreurs ne sont pas si difficiles à lire.


20

J'ai converti votre programme de PNG en ASCII, mais il ne se compile pas encore. Pour votre information, j'ai essayé avec une largeur de ligne de 100 et 250 caractères mais les deux donnent des résultats comparables.

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

8
Vous devriez probablement utiliser 80 ou même 72 colonnes à la place
Tobias Kienzler

16

Le premier problème est que vous essayez de renvoyer une valeur incorrecte à la fin de la fonction principale. La norme C ++ dicte que le type de retour de main () est int, mais à la place, vous essayez de renvoyer l'ensemble vide.

L'autre problème est - au moins avec g ++ - que le compilateur déduit la langue utilisée du suffixe de fichier. De g ++ (1):

Pour tout fichier d'entrée donné, le suffixe du nom de fichier détermine le type de compilation à effectuer:

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

Code source C ++ qui doit être prétraité. Notez qu'en .cxx, les deux dernières lettres doivent toutes deux être littéralement x. De même, .C fait référence à un majuscule littéral C.

La résolution de ces problèmes devrait vous laisser une application Hello World pleinement fonctionnelle, comme vous pouvez le voir dans la démo ici .


3
J'avais un professeur en arrière quand qui décollerait vos points de devoirs ou d'examens si vous mettez une barre oblique à zéro car le zéro n'est pas l'ensemble nul. Il apprécierait cette réponse.
Michael Burr

15

Votre police craint, comment un analyseur devrait-il être capable de lire cela? Suivez un cours de calligraphie.


13

Vos compilateurs attendent ASCII , mais ce programme est évidemment écrit en utilisant EBCDIC .


Enfin, j'ai entendu que C ++ ne spécifie pas que les programmes doivent être écrits en ASCII, UTF-8 ou quoi que ce soit d'autre.
Adrian Ratnapala

8

Vous essayez de compiler une image.

Tapez ce que vous avez écrit à la main dans un document appelé main.cpp, exécutez ce fichier via votre compilateur, puis exécutez le fichier de sortie.


23
Vérifiez la date sur votre PC.
James P.

14
Haha, mais j'ai finalement trouvé une réponse facile à laquelle je pourrais répondre!
Cody Gray

10
C'est idiot. Nous savons tous que le compilateur optimiserait les espaces blancs, ne laissant que des espaces noirs fortement compressés, qui sont tous les uns et seraient compressés en un binaire 1 qui serait renvoyé comme une erreur. Le code devait être écrit à l'aide de blanc qui se compilerait à 0 et ne retournerait pas d'erreur.
The Tin Man

7

Vous devez spécifier la précision de votre sortie précédée de deux points juste avant l'accolade de fermeture finale . Comme la sortie n'est pas numérique, la précision est nulle, vous avez donc besoin de cela -

: 0}


5

ajouter :

using namespace std;

juste après inclure: P: D


5
Je préfère taper stdtout le temps. Me rappelle de ne pas en avoir un.
Mateen Ulhaq

5

Semble que votre compilateur ne prend pas en charge les fichiers dans un tel codage hmm .... Essayez de le convertir en ASCII.


5

Le problème réside dans la définition de la syntaxe, essayez d'utiliser la règle et les boussoles pour une description plus classique!

À votre santé,


5

Essayez de changer d'interface d'entrée. C ++ s'attend à ce qu'un clavier soit connecté à votre ordinateur, pas un scanner. Il peut y avoir des problèmes de conflit de périphériques ici. Je n'ai pas vérifié dans la norme ISO si l'interface d'entrée au clavier est obligatoire, mais cela est vrai pour tous les compilateurs que j'ai jamais utilisés. Mais peut-être que l'entrée du scanner est maintenant disponible en C99, et dans ce cas, votre programme devrait en effet fonctionner. Sinon, vous devrez attendre la prochaine version standard et la mise à niveau des compilateurs.


5

Vous pouvez essayer différentes couleurs pour les supports, peut-être qu'un peu de vert ou de rouge vous aiderait? Je pense que votre compilateur ne peut pas reconnaître l'encre noire: P


5

Suis-je le seul à ne pas reconnaître le caractère entre «retour» et le point-virgule? Ça pourrait être ça!


4
C'est une lettre majuscule O avec une ligne spéciale que nous appelons "diamètre", qui indique au compilateur d'utiliser l'algorithme du cercle médian, évidemment. Je pense que vous devriez vérifier vos yeux.
Mateen Ulhaq
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.