Why is this program erroneously rejected by three C++ compilers?
编译我编写的C++程序有些困难。
这个程序非常简单,而且,据我所知,它符合C++标准中规定的所有规则。我已经读了两遍ISO/IEC 14882:2003的全部内容。
程序如下:
这里是我尝试用Visual C++ 2010编译这个程序时所收到的输出:
1 2 3 | 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,但同样没用:
1 2 3 | c:\dev>g++ helloworld.png helloworld.png: file not recognized: File format not recognized collect2: ld returned 1 exit status |
我认为clang(3.0版Trunk 127530)必须工作,因为它的标准一致性受到了高度赞扬。不幸的是,它甚至没有给我一条漂亮的、突出显示的错误消息:
1 2 3 4 | 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,但没用。我认为有一个非常严重的错误在叮当声,因为当我试图用它来编译重命名的程序时,它突然弹出来,打印"84个警告和20个错误产生",并使我的电脑发出很多哔哔声!
我在这里做错了什么?我是否错过了C++标准的一些关键部分?或者这三个编译器真的都太坏了以至于他们不能编译这个简单的程序?
你的
在本标准中,§2.1/1规定:
Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary.
您的编译器不支持这种格式(aka无法将其映射到基本源字符集),因此它无法进入进一步的处理阶段,因此会出现错误。编译器完全可能支持从映像到基本源字符集的映射,但不需要这样做。
因为这个映射是实现定义的,所以您需要查看实现文档,以查看它支持的文件格式。通常,每个主要编译器供应商都支持(规范定义的)文本文件:由文本编辑器生成的任何文件,通常是一系列字符。
请注意,C++标准是基于C标准(第1.1或2),C(99)标准表示,在第1.2节:
This International Standard does not specify
— the mechanism by which C programs are transformed for use by a data-processing
system;
— the mechanism by which C programs are invoked for use by a data-processing
system;
— the mechanism by which input data are transformed for use by a C program;
因此,同样,源文件的处理也是您需要在编译器文档中找到的。
您可以尝试下面的python脚本。注意,您需要安装pil和pytesser。
1 2 3 | from pytesser import * image = Image.open('helloworld.png') # Open image object using PIL print image_to_string(image) # Run tesseract.exe on image |
要使用它,请:
1 | python script.py > helloworld.cpp; g++ helloworld.cpp |
你忘了用漫画字体,这就是为什么它会出错。
我看不到在最后一个支撑后有新的线条。
如您所知:"如果一个非空的源文件不以新行字符结尾,…行为未定义"。
这个程序是有效的——我找不到错误。
我猜你的机器上有病毒。最好是重新格式化驱动器并重新安装操作系统。
如果您需要有关重新安装的帮助,请告诉我们解决方法。
我讨厌病毒。
我发现用魔术笔不在显示器玻璃上写代码是有帮助的,即使它真的是黑色的时候看起来很漂亮。屏幕填充得太快,然后给我一个干净的显示器的人每周都给我起名字。
我的几个雇员(我是经理)凑钱给我买了一台带旋钮的红色笔记本电脑。他们说我不需要记号笔,满了的时候我可以自己清理屏幕,但我必须小心摇晃它。我想那样很精致。
这就是我雇用聪明人的原因。
你忘了前置处理器。试试这个:
1 | pngtopnm helloworld.png | ocrad | g++ -x 'c++' - |
你手写程序然后扫描到电脑里了吗?这就是"helloworld.png"所暗示的。如果是这样的话,你需要知道C++标准(甚至在它的最新版本)不需要存在光学字符识别,不幸的是它不被包含在任何当前编译器中的可选特征中。
您可能需要考虑将图形转换为文本格式。可以使用任何纯文本编辑器;使用字处理器,虽然能够生成一个漂亮的打印输出,但很可能会导致与尝试扫描时相同的错误。
如果你真的很冒险,你可以试着把代码写进文字处理器。打印它,最好使用像OCR-A这样的字体。然后,把打印出来的文件放回去扫描。然后可以通过第三方OCR包运行扫描以生成文本表单。然后可以使用许多标准编译器之一来编译文本表单。
然而,要注意在调试阶段这将产生巨大的纸张成本。
绘制下面的include以使其编译:
1 | #include <ChuckNorris> |
我听说他能编译语法错误…
不幸的是,您已经选择了三种编译器,它们都支持多种语言,而不仅仅是C++。他们都必须猜测你使用的编程语言。正如您可能已经知道的,PNG格式适用于所有的编程语言,而不仅仅是C++。
通常编译器可以计算出语言本身。例如,如果PNG明显是用蜡笔绘制的,编译器就会知道它包含VisualBasic。如果它看起来像是用机械铅笔画的,那么很容易识别工作中的工程师,编写Fortran代码。
在本例中,第二步对编译器也没有帮助。C和C++看起来太相似了,降到EDCOX1的0Ω。因此,您必须帮助编译器决定它到底是什么语言。现在,您可以使用非标准方法。例如,VisualStudio编译器接受/TC和/TP命令行参数,或者您可以在项目文件中使用"编译为:C++"选项。GCC和Clang有自己的机制,我不知道。
因此,我建议使用标准方法来告诉编译器代码遵循C++。正如你现在发现的,C++编译器对他们所接受的东西非常挑剔。因此,识别C++的标准方法是通过恐吓程序员添加到C++代码中。例如,下面的行将向编译器阐明以下内容是C++(并且他最好在没有抱怨的情况下编译它)。
1 | // To the compiler: I know where you are installed. No funny games, capice? |
试试这个:
您的编译器是否设置为专家模式?!如果是,则不应编译。现代编纂者厌倦了"你好,世界!"
OCR说:
1 2 3 4 5 6 7 8 9 | 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 _ | _| |
公平地说,这真是太好了。
helloworld.png: file not recognized: File format not recognized
显然,您应该格式化硬盘。
实际上,这些错误并不难理解。
我确实将您的程序从png转换为ascii,但它还没有编译。为了您的信息,我尝试了行宽100和250个字符,但两者都得到了类似的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ` ` . `. ` ... +:: ..-.. --.:`:. `-` .....:`../--`.. `- ` ` ```` ` ` `` .` `` .` `. `` . -``- .. .`--`:` :::.-``-. : ``.-`- `-.-`:.-` :-`/.-..` ` `-..`...- : .` ` ` ` .` ````:`` - ` ``-.` ` `- .. `` . ` .`. ` ` `. ` . . ` . ` . . .` .` ` ` `` ` ` `:`.`:` ` -..-`.`- .-`-. /.-/.-`.-. -...-..`- :``` `-`-` :`..`-` ` :`.`:`- ` `` ` ```. `` ```` ` ` ` ` ` ` ` . : -...`.- .` .:/ ` - ` `` . -` ` |
第一个问题是,您试图在主函数末尾返回错误的值。C++标准规定,返回的主类型()类型是int,但您尝试返回空集。
另一个问题是——至少对于g++——编译器从文件后缀推断所使用的语言。从G++(1):
For any given input file, the file
name suffix determines what kind of
compilation is done:file.cc file.cp file.cxx file.cpp file.CPP file.c++ file.C
C ++ source code which must be preprocessed. Note that in .cxx, the
last two letters must both be literally x. Likewise, .C refers to a
literal capital C.
修复这些应该会给您留下一个完全工作的hello world应用程序,从这里的演示可以看到。
你的字体糟透了,解析器怎么能读出来呢?上书法课。
您的编译器需要使用ASCII,但该程序显然是使用EBCDIC编写的。
您正在尝试编译图像。
输入您手写到名为main.cpp的文档中的内容,通过编译器运行该文件,然后运行输出文件。
您需要在最后一个右大括号之前指定输出的精度,该精度前面紧跟一个冒号。由于输出不是数字,所以精度为零,因此需要这样做-
:0 }
似乎您的编译器不支持这种hmm中的文件…编码。尝试将其转换为ASCII。
添加:
1 | using namespace std; |
包括之后:P:D
尝试切换输入接口。C++希望将键盘插入计算机,而不是扫描器。这里可能存在外围设备冲突问题。如果键盘输入接口是必需的,我没有签入ISO标准,但对于我使用过的所有编译器来说,这是正确的。但是,也许现在C99中有扫描仪输入,在这种情况下,您的程序确实可以工作。否则,您将不得不等待编译器的下一个标准版本和升级。
你可以尝试不同颜色的括号,也许一些绿色或红色会有帮助?我认为你的编译器不能识别黑色墨水:p
我是唯一一个不能识别"回车"和分号之间的字符的人吗?可能就是这样!
问题在于语法定义,请尝试使用标尺和圆规进行更经典的描述!
干杯,
通过OCR运行编译器。它可以解决兼容性问题。