为什么该程序被三个C ++编译器错误地拒绝?


468

我在编译我编写的C ++程序时遇到了一些困难。

该程序非常简单,据我所知,它符合C ++标准中列出的所有规则。我已经阅读了两次完整的ISO / IEC 14882:2003,以确保。

该程序如下:

在此处输入图片说明

这是尝试使用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

沮丧的是,我尝试了g ++ 4.5.2,但同样没有帮助:

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

我认为Clang(3.0版主干127530版)必须能够工作,因为它的标准一致性倍受赞誉。不幸的是,它甚至没有给我提供其漂亮的,突出显示的错误消息之一:

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)

老实说,我真的不知道这些错误消息是什么意思。

许多其他C ++程序都具有带有.cpp扩展名的源文件,因此我想也许我需要重命名文件。我将其名称更改为helloworld.cpp,但这没有帮助。我认为Clang中有一个非常严重的错误,因为当我尝试使用它来编译重命名的程序时,它翻转了,并显示“ 84警告和20错误生成”。让我的电脑发出很多哔哔声!

我在这里做错了什么?我是否错过了C ++标准的某些关键部分?还是所有三个编译器真的都坏了,无法编译这个简单的程序?

Answers:


173

在标准中,第2.1 / 1节规定:

如有必要,物理源文件字符将以实现定义的方式映射到基本源字符集(为行尾指示符引入换行符)。

您的编译器不支持该格式(也无法将其映射到基本源字符集),因此它无法进入进一步的处理阶段,因此会出现错误。您的编译器完全有可能支持从图像到基本源字符集的映射,但不是必需的。

由于此映射是实现定义的,因此您需要查看实现文档以查看其支持的文件格式。通常,每个主要的编译器供应商都支持(规范定义)文本文件:文本编辑器生成的任何文件,通常是一系列字符。


请注意,C ++标准基于C标准(第1.1 / 2节),而C(99)标准在第1.2节中说:

本国际标准未指定
-转换C程序以供数据处理系统使用的机制;
—调用C程序以供数据处理系统使用的机制;
—转换输入数据以供C程序使用的机制;

因此,同样,您需要在编译器文档中找到对源文件的处理。


23
我认为那句话充其量是模棱两可的。Merriam-Webster词典说,文字书面或印刷作品包含此类文字的作品的原始单词和形式。该源文件显然属于该定义。您认为我应该向核心语言工作组提交缺陷报告吗?
James McNellis

15
哦; 我完全忘记阅读所有参考文件。我认为该段落是脱离上下文的,因此,我将阅读ISO / IEC 9899:1990的全部内容,并在我完全理解后将其重新发布。
James McNellis 2011年



211

<>(){}似乎并不匹配得非常好; 尝试更好地绘制它们。


44
虽然我不喜欢您取笑我的笔迹,但这可能是真正的问题,并且可以解释当我尝试使用Visual C ++ 编译重命名的helloworld.cpp时遇到的错误:“严重错误C1004:找到文件”,我将再试一次,并尽快返回报告。谢谢!
James McNellis 2011年

37
@James确保关闭所有png优化。它使调试更加容易。
wilhelmtell

5
@James:“意外的文件结尾”几乎可以肯定}是导致问题的原因是您。尝试着重与{
Carson63000

156

您可以尝试以下python脚本。请注意,您需要安装PILpytesser

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

要使用它,请执行以下操作:

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

110

您忘了将Comic Sans用作字体,这就是为什么它会出错。


73
不幸的是,这是我的手唯一支持的字体。因此,如果我不能用C ++编程,那将是非常可悲的。您认为Java支持该字体吗?
James McNellis 2011年

8
无论如何,当您想到绘制漫画时,都将需要Comic Sans,因此您应该认真考虑升级手。
sharptooth

8
C ++需要进行为期一年的书法培训。如果您没有时间,请尝试使用Visual Basic或尝试二进制机器代码(然后只需要获得0和1)即可。
弗兰克·奥斯特菲尔德

1
@Frank C ++ 0x§42.1/ 1指定“所有字符串都必须为哥特式”。
Mateen Ulhaq 2011年

75

在最后一个括号之后,我看不到换行符。

如您所知:“如果源文件不为空,则不会以换行符结尾,则...行为未定义”。


16
嗯 幸运的是,这个荒谬的规则已在C ++ 0x中删除。也就是说,如何用换行符结束这样的文件?我以为我在文本末尾留了足够的空间(如果突出显示源文件,则应该看到我剩下的多余空间)。不过,感谢您的提示!
James McNellis 2011年

8
如果您没有足够的空格,我可以尝试在系统上进行编译。我有四个监视器,因此我可以尝试从最左边的一个进行编译。
锡人

74

该程序有效-我找不到错误。

我的猜测是您的计算机上有病毒。最好重新格式化驱动器,然后重新安装操作系统。

让我们知道如何解决,或者如果您需要重新安装方面的帮助。

我讨厌病毒。


17
是的,尝试安装Linux。我将问题归咎于Windows。
Raedwald,

62

我发现不要用魔术笔在显示器的玻璃上写代码,即使它看起来很黑也不错。屏幕填满的速度太快,然后每周给我干净的显示器的人给我打电话。

我的几个员工(我是经理)正在努力向我购买带有旋钮的那台红色平板电脑。他们说我不需要记号笔,可以在屏幕满时自行清洁屏幕,但是我必须小心摇晃它。我以为这样很精致。

这就是为什么我雇用聪明的人。


2
Wacom Cintiq更适合经理。它很昂贵,让您感到非常重要。公司中的任何图形设计师的地位将低得多,因此应使用EGA监视器。管理员应使用CGA监视器。程序员应使用二手单色端子。
Steve314 2011年

7
我有一台“ Life Like”监视器已经很长时间了。如此现实,以至于您发誓要游泳的屏幕保护程序是真实的,而那个小潜水员看上去就像他在游泳。我一直弄湿我的手臂,试图从底部拿起宝箱,那真是太真实了。唯一的问题是屏幕保护程序始终处于打开状态,并且逼真的起泡声使它很难听到。哦,他们说,为了进行维护,我每天必须在显示器顶部撒些东西,否则屏幕保护程序将停止工作。这样做一次,男孩,两天后的气味真的很真实。
Tin Man

59

File format not recognized您需要正确格式化文件。这意味着为代码使用正确的颜色和字体。请参阅每个编译器的特定文档,因为这些颜色在编译器之间会有所不同;)


14
哦,这很有道理...我有一盒96支蜡笔,所以我确定我的前景色是正确的。明天我将拿起一些彩色的建筑用纸,并尝试使用其他颜色的纸。
James McNellis

3
为了安全起见,最好还添加一些彩色铅笔和油性涂料。众所周知,C ++是很难正确格式化的语言。
helloworld922

是的,不要忘记使用突出显示标记。
sharptooth

6
@sharptooth-语法高亮显示是IDE的功能-您无意手动执行此操作。因此,请确保您有一个机械臂与该突出显示标记一起使用。
Steve314 2011年

56

您忘记了预处理器。尝试这个:

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

8
哦! 我以为预处理器已包含在编译器中!我将尝试找到可在Windows笔记本电脑上使用的预处理器。
James McNellis 2011年

3
@James McNellis:预处理器不是程序,它是硬件,看起来像是突出显示的标记-将其移至文本上方并进行预处理。
sharptooth 2011年

49

您是否手写了程序,然后将其扫描到计算机中?那就是“ helloworld.png”所暗示的。如果真是这样,您需要知道C ++标准(即使是最新版本)也不需要光学字符识别,而且遗憾的是,当前任何编译器均未将其包含为可选功能。

您可能需要考虑将图形转换为文本格式。可以使用任何纯文本编辑器;使用文字处理器虽然能够生成漂亮的打印输出,但很可能会导致与尝试扫描时出现的错误相同的错误。

如果您确实喜欢冒险,可以尝试将代码编写到文字处理器中。打印,最好使用OCR-A之类的字体。然后,取出您的打印输出并扫描回去。然后可以通过第三方OCR软件包运行扫描,以生成文本表单。然后可以使用许多标准编译器之一来编译文本表单。

但是,请注意,在调试阶段会花费大量纸张。


鸡与蛋的困境:是否可以为OCR软件编写C ++代码并在没有OCR的情况下进行编译?
jweyrich 2011年

5
好吧,您将原始OCR使用汇编语言。
凯文·拉奎蒙

@jweyrich-我认为您首先需要使用asm / OCR工具链来引导C ++ / OCR。
Michael Burr

2
哦,ASM,是的!打孔卡中的ASM
jweyrich


40

不幸的是,您选择了三个都支持多种语言的编译器,而不仅仅是C ++。他们都必须猜测您使用的编程语言。您可能已经知道,PNG格式适用于所有编程语言,而不仅仅是C ++。

通常,编译器可以弄清楚语言本身。例如,如果显然用蜡笔绘制了PNG,则编译器将知道它包含Visual Basic。如果看起来像是用自动铅笔绘制的,则很容易识别工作中的工程师,他们正在编写FORTRAN代码。

在这种情况下,第二步也无济于事。C和C ++看起来太相似了,一直到#include。因此,您必须帮助编译器确定其真正的语言。现在,您可以使用非标准方式。例如,Visual Studio编译器接受/ TC和/ TP命令行参数,或者您可以在项目文件中使用“编译为:C ++”选项。GCC和CLang有自己的机制,我不知道。

因此,我建议改用标准方法来告诉编译器以下代码是C ++。正如您现在所发现的,C ++编译器对于接受的内容非常挑剔。因此,识别C ++的标准方法是由程序员添加到他们的C ++代码中来。例如,以下几行将向您的编译器说明,其后是C ++(他最好编译而不会抱怨)。

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

10
我认为这#pragma是向编译器“获取消息”的正确方法吗?
Lev Bishop

33

试试这个:

您在航天飞机上看到恐龙了吗?


4
我认为有一个错字-应该是endl(L)而不是end1(一个)。但是+1做得很好!
Rup

44
我已经盯着这个看了三个小时,但我仍然看不到恐龙或航天飞机。:-(
oosterwal 2011年

32

您的编译器是否设置为专家模式?如果是,则不应编译。现代编译器已经厌倦了“ Hello World!”。


27

OCR说:

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

公平地说,这真是太好了。


4
哇,自从我尝试扫描笔迹以来,OCR已有所改善(也花了几个小时直接笔迹)。
James P.

40
我认为我们需要添加一个Perl标签。
MSalters 2011年

26

helloworld.png:文件无法识别:文件格式无法识别

显然,您应该格式化硬盘。

确实,这些错误并不难读。


20

我确实将您的程序从PNG转换为ASCII,但尚未编译。为了给您提供信息,我尝试使用100和250个字符的行宽,但是两者的结果都差不多。

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

8
你或许应该使用80个或72甚至列,而不是
托比亚斯Kienzler

16

第一个问题是,您试图在main函数末尾返回错误的值。C ++标准规定main()的返回类型为int,但是您尝试返回空集。

另一个问题是-至少对于g ++-编译器从文件后缀中推导了所使用的语言。从g ++(1):

对于任何给定的输入文件,文件名后缀确定完成哪种编译:

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

必须预处理的C ++源代码。请注意,在.cxx中,最后两个字母都必须为x。同样,.C表示文字大写C。

修复这些应该留给你一个完全正常的Hello World应用程序,这可以从演示中可以看出这里


3
我有个教授的路,如果您将斜线放在零位,因为零不是空集,那么谁来完成您的作业或考试呢?他将不胜感激。
Michael Burr



8

您正在尝试编译图像。

输入您手写到main.cpp文档中的内容,通过编译器运行该文件,然后运行输出文件。


23
在电脑上检查日期。
James P.

14
哈哈,但是我终于找到了一个我可以回答的简单问题!
科迪·格雷

10
真傻 我们都知道,编译器将优化空白,仅保留高度压缩的黑色空间,这些空间全部为1,并将压缩为二进制1,并将其作为错误返回。需要使用掉电编写代码,该掉电将编译为0且不返回错误。
Tin Man

7

您需要指定输出的精度,并在最后一个大括号之前紧接冒号。由于输出不是数字,因此精度为零,因此您需要-

:0}




5

问题在于语法定义,请尝试使用标尺和指南针进行更经典的描述!

干杯,


5

尝试切换输入接口。C ++希望将键盘而非扫描仪插入计算机。这里可能存在外围设备冲突问题。如果键盘输入接口是强制性的,我没有检查ISO标准,但是对于我使用过的所有编译器都是如此。但是也许C99中现在提供了扫描仪输入,在这种情况下,您的程序确实应该可以运行。否则,您将不得不等待下一个标准版本和编译器的升级。


5

您可以尝试使用不同颜色的括号,也许一些绿色或红色会有所帮助?我认为您的编译器无法识别黑色墨水:P


5

我是唯一无法识别“返回”和分号之间字符的人吗?就是这样!


4
这是一个大写字母O,带有特殊行,我们称其为“直径”,这显然告诉编译器使用中点圆算法。我认为您应该检查一下眼睛。
Mateen Ulhaq 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.