¿Por qué este programa es rechazado erróneamente por tres compiladores de C ++?


468

Tengo dificultades para compilar un programa C ++ que he escrito.

Este programa es muy simple y, que yo sepa, cumple con todas las reglas establecidas en el Estándar C ++. He leído dos veces la totalidad de ISO / IEC 14882: 2003 para estar seguro.

El programa es el siguiente:

ingrese la descripción de la imagen aquí

Aquí está el resultado que recibí al intentar compilar este programa 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

Consternado, probé g ++ 4.5.2, pero fue igualmente inútil:

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

Pensé que Clang (versión 3.0 troncal 127530) debe funcionar, ya que es muy elogiado por su conformidad con los estándares. Desafortunadamente, ni siquiera me dio uno de sus mensajes de error bonitos y destacados:

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)

Para ser honesto, realmente no sé qué significan estos mensajes de error.

Muchos otros programas de C ++ tienen archivos de origen con una extensión .cpp , así que pensé que tal vez necesitaba cambiar el nombre de mi archivo. Cambié su nombre a helloworld.cpp , pero eso no ayudó. Creo que hay un error muy grave en Clang porque cuando intenté usarlo para compilar el programa renombrado, se volteó e imprimió "84 advertencias y 20 errores generados". e hizo que mi computadora emitiera un pitido mucho

¿Qué he hecho mal aquí? ¿Me he perdido alguna parte crítica del estándar C ++? ¿O los tres compiladores están realmente tan rotos que no pueden compilar este sencillo programa?

Respuestas:


173

En el estándar, §2.1 / 1 especifica:

Los caracteres del archivo de origen físico se asignan, de una manera definida por la implementación, al conjunto de caracteres de origen básico (introduciendo caracteres de nueva línea para indicadores de fin de línea) si es necesario.

Su compilador no admite ese formato (es decir, no puede asignarlo al conjunto de caracteres de origen básico ), por lo que no puede pasar a otras etapas de procesamiento, de ahí el error. Es completamente posible que su compilador admita un mapeo desde la imagen al juego de caracteres fuente básico, pero no es obligatorio.

Como esta asignación está definida por la implementación, deberá consultar la documentación de sus implementaciones para ver los formatos de archivo que admite. Por lo general, todos los principales proveedores de compiladores admiten archivos de texto (definidos canónicamente): cualquier archivo producido por un editor de texto, generalmente una serie de caracteres.


Tenga en cuenta que el estándar C ++ se basa en el estándar C (§1.1 / 2), y el estándar C (99) dice, en §1.2:

Esta Norma Internacional no especifica
: el mecanismo por el cual los programas C se transforman para su uso por un sistema de procesamiento de datos;
- el mecanismo por el cual los programas C son invocados para su uso por un sistema de procesamiento de datos;
- el mecanismo por el cual los datos de entrada se transforman para su uso por un programa en C;

Entonces, nuevamente, el tratamiento de los archivos fuente es algo que necesita encontrar en la documentación de sus compiladores.


23
Creo que esa oración es ambigua en el mejor de los casos. El diccionario Merriam-Webster dice que el texto son las palabras y la forma originales de una obra escrita o impresa o una obra que contiene dicho texto . Este archivo fuente claramente cae bajo esa definición. ¿Crees que debería presentar un informe de defectos al Core Language Working Group?
James McNellis 01 de

15
Oh; Olvidé por completo leer todos los documentos referenciados. Sin embargo, creo que ese párrafo está fuera de contexto, por lo que iré a leer la totalidad de ISO / IEC 9899: 1990 y volveré a publicar aquí una vez que lo entienda completamente.
James McNellis el



211

Tu <y >, (y ), {y }no parecen coincidir muy bien; Intenta dibujarlos mejor.


44
Si bien no aprecio que te burles de mi letra, este podría ser el verdadero problema, y ​​explicaría el error que obtengo cuando intento compilar el renombrado helloworld.cpp con Visual C ++: "error fatal C1004: final inesperado de- archivo encontrado "Volveré a intentarlo e informaré pronto ¡Gracias!
James McNellis 01 de

37
@ James, asegúrese de desactivar todas las optimizaciones png. Facilita la depuración.
wilhelmtell 01 de

55
@James: "fin de archivo inesperado" casi seguramente significa que es usted }quien está causando el problema. Trate de concentrarse en la coincidencia de que con el{
Carson63000

156

Puedes probar el siguiente script de Python. Tenga en cuenta que necesita instalar PIL y pytesser .

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

Para usarlo, haz:

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

110

Olvidó usar Comic Sans como fuente, por eso es un error.


73
Desafortunadamente, esta es la única fuente que admite mi mano. Eso sería muy triste si no puedo programar en C ++ debido a esto. ¿Crees que Java admitiría esta fuente?
James McNellis 01 de

8
Necesitarás Comic Sans cuando pienses en dibujar cómics de todos modos, por lo que deberías considerar seriamente mejorar las manos.
Sharptooth

8
C ++ requiere entrenamiento de un año en caligrafía. Si no tiene el tiempo, intente con Visual Basic o solo con el código de máquina binario (solo tiene que obtener los 0 y 1 en ese momento).
Frank Osterfeld

1
@Frank C ++ 0x §42.1 / 1 especifica "Todas las cadenas deben estar en gótico".
Mateen Ulhaq

75

No puedo ver una nueva línea después de ese último aparato ortopédico.

Como sabe: "Si un archivo fuente que no está vacío no termina en un carácter de nueva línea, ... el comportamiento no está definido".


16
Hmmm Afortunadamente, esta regla ridícula se ha eliminado en C ++ 0x. Dicho esto, ¿cómo termina uno de esos archivos con una nueva línea? Pensé que había dejado suficiente espacio al final del texto (si resalta el archivo fuente, debería ver el espacio adicional que dejé). ¡Gracias por el consejo!
James McNellis 01 de

8
Si no tiene suficiente espacio en blanco, puedo intentar compilarlo en mi sistema. Tengo cuatro monitores, así que podría intentar compilar desde mi extremo izquierdo.
The Tin Man

74

Este programa es válido, no puedo encontrar errores.

Supongo que tienes un virus en tu máquina. Sería mejor si reformatea su unidad y reinstala el sistema operativo.

Háganos saber cómo funciona, o si necesita ayuda con la reinstalación.

Odio los virus


17
Sí, intente instalar Linux. Culpo a Windows por tu problema.
Raedwald

62

He descubierto que ayuda no escribir mi código en el cristal de mi monitor con un marcador mágico, aunque se ve bien cuando es realmente negro. La pantalla se llena demasiado rápido y luego las personas que me dan un monitor limpio me llaman cada semana.

Un par de mis empleados (soy un gerente) están contribuyendo para comprarme una de esas computadoras de almohadilla roja con las perillas. Dijeron que no necesitaré marcadores y que puedo limpiar la pantalla yo mismo cuando esté llena, pero tengo que tener cuidado de sacudirla. Supuse que es delicado de esa manera.

Por eso contrato a las personas inteligentes.


2
Un Wacom Cintiq es mucho más apropiado para un gerente. Es caro y te hace sentir realmente importante. Cualquier diseñador gráfico en su empresa tendrá un estado mucho más bajo y, por lo tanto, debería usar monitores EGA. Los conserjes deben usar monitores CGA. Los programadores deben usar terminales monocromos de segunda mano.
Steve314

77
Tuve un monitor "Life Like" durante mucho tiempo. Era tan realista que juraría que el salvapantallas de los peces nadadores era real, y el pequeño buzo parecía que estaba nadando. Seguí mojándome el brazo tratando de sacar el cofre del tesoro desde el fondo, era tan real. El único problema era que el protector de pantalla siempre estaba activado y los ruidos burbujeantes realistas dificultaban la audición. Ah, y dijeron que para el mantenimiento tenía que rociar cosas en la parte superior del monitor a diario o el protector de pantalla dejaría de funcionar. Lo hizo una vez, y vaya, el olor dos días después fue muy realista.
The Tin Man

59

File format not recognizedNecesita formatear correctamente su archivo. Eso significa usar los colores y fuentes correctos para su código. Vea las documentaciones específicas para cada compilador ya que estos colores varían entre compiladores;)


14
Oh, eso tiene sentido ... Tengo una caja de 96 crayones, así que estoy seguro de que tengo el color de primer plano correcto. Recogeré un poco de papel de construcción de color mañana y lo probaré en un color de papel diferente.
James McNellis 01 de

3
Solo para estar seguros, es mejor que también consigas algunos lápices de colores y pintura a base de aceite. Es un hecho bien conocido que C ++ está destinado a ser un lenguaje muy difícil de formatear correctamente.
helloworld922

Yeap, y no olvides usar el marcador de resaltado.
Sharptooth

66
@sharptooth: el resaltado de sintaxis es una función IDE; no debe hacerlo a mano. Así que asegúrese de obtener un brazo robótico que vaya con ese marcador de resaltado.
Steve314

56

Olvidaste el preprocesador. Prueba esto:

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

8
Oh! ¡Pensé que el preprocesador estaba incluido con el compilador! Trataré de encontrar un preprocesador que funcione en mi computadora portátil con Windows.
James McNellis 01 de

3
@James McNellis: El preprocesador no es un programa, es una cosa de hardware que parece un marcador de resaltado: lo mueve sobre el texto y se procesa previamente.
Sharptooth

49

¿Escribiste a mano el programa y luego lo escaneaste en la computadora? Eso es lo que implica "helloworld.png". Si ese es el caso, debe tener en cuenta que el estándar C ++ (incluso en su última edición) no requiere la presencia de reconocimiento óptico de caracteres, y desafortunadamente no está incluido como una característica opcional en ningún compilador actual.

Es posible que desee considerar la transposición de los gráficos a un formato de texto. Se puede usar cualquier editor de texto sin formato; El uso de un procesador de texto, si bien es capaz de generar una impresión bonita, probablemente dará como resultado el mismo error que se obtiene al intentar escanear.

Si eres realmente aventurero, puedes intentar escribir tu código en un procesador de textos. Imprima, preferiblemente usando una fuente como OCR-A . Luego, tome su copia impresa y vuelva a escanearla. La exploración puede ejecutarse a través de un paquete de OCR de terceros para generar un formulario de texto. El formulario de texto se puede compilar utilizando uno de los muchos compiladores estándar.

Sin embargo, tenga cuidado con el gran costo del papel en el que incurrirá durante la fase de depuración.


El dilema del huevo y la gallina: ¿es posible escribir código C ++ para un software de OCR y compilarlo sin un OCR?
jweyrich 01 de

55
Bueno, duh, usas ensamblaje para el OCR original.
Kevin Lacquement

@jweyrich: creo que primero tendrás que arrancar tu C ++ / OCR con tu cadena de herramientas asm / OCR.
Michael Burr


46

Dibuje la inclusión a continuación para compilarla:

#include <ChuckNorris>

Escuché que puede compilar errores de sintaxis ...


46
Prefiero personalmente #include <JonSkeet>.
Icode4food 01 de

40

Desafortunadamente, seleccionó tres compiladores que admiten múltiples lenguajes, no solo C ++. Todos tienen que adivinar el lenguaje de programación que usaste. Como probablemente ya sepa, el formato PNG es adecuado para todos los lenguajes de programación, no solo C ++.

Por lo general, el compilador puede descubrir el lenguaje en sí. Por ejemplo, si el PNG obviamente se dibuja con crayones, el compilador sabrá que contiene Visual Basic. Si parece que está dibujado con un lápiz mecánico, es fácil reconocer al ingeniero en el trabajo, escribiendo código FORTRAN.

Este segundo paso tampoco ayuda al compilador, en este caso. C y C ++ simplemente se ven muy similares, hasta el #include. Por lo tanto, debe ayudar al compilador a decidir qué idioma es realmente. Ahora, podría usar medios no estándar. Por ejemplo, el compilador de Visual Studio acepta los argumentos de línea de comandos / TC y / TP , o puede usar la opción "Compilar como: C ++" en el archivo del proyecto. GCC y CLang tienen sus propios mecanismos, que no sé.

Por lo tanto, recomendaría usar el método estándar en su lugar para decirle a su compilador que el siguiente código está en C ++. Como ya descubrió, los compiladores de C ++ son muy exigentes con lo que aceptan. Por lo tanto, la forma estándar de identificar C ++ es mediante la intimidación que los programadores agregan a su código C ++. Por ejemplo, la siguiente línea le aclarará a su compilador que lo que sigue es C ++ (y será mejor que lo compile sin quejas).

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

10
¿Pensé que #pragmaera la forma correcta de "enviar un mensaje" al compilador?
Lev Bishop

33

Prueba este:

¿Ves el dinosaurio en el transbordador espacial?


44
Creo que hay un error tipográfico: debería ser endl(L) no end1(uno). ¡Pero +1 bien hecho!
Rup

44
He estado mirando esto durante tres horas, pero todavía no puedo ver un dinosaurio o el transbordador espacial. :-(
oosterwal

32

¿Está su compilador configurado en modo experto? Si es así, no debería compilarse. Los compiladores modernos están cansados ​​de "¡Hola Mundo!"


27

OCR dice:

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

Lo cual es bastante bueno, para ser justos.


44
Wow, OCR ha mejorado desde que intenté escanear mi letra (también pasé horas escribiéndola directamente).
James P.

40
Creo que necesitamos agregar una etiqueta Perl.
MSalters

26

helloworld.png: archivo no reconocido: formato de archivo no reconocido

Obviamente, debe formatear su disco duro.

Realmente, estos errores no son tan difíciles de leer.


20

Convertí su programa de PNG a ASCII, pero aún no se compila. Para su información, intenté con un ancho de línea de 100 y 250 caracteres, pero ambos arrojaron resultados comparables.

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

8
Probablemente deberías usar 80 o incluso 72 columnas en su lugar
Tobias Kienzler

16

El primer problema es que está intentando devolver un valor incorrecto al final de la función principal. El estándar C ++ dicta que el tipo de retorno de main () es int, pero en su lugar está intentando devolver el conjunto vacío.

El otro problema es, al menos con g ++, que el compilador deduce el lenguaje utilizado del sufijo del archivo. De g ++ (1):

Para cualquier archivo de entrada dado, el sufijo del nombre de archivo determina qué tipo de compilación se realiza:

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

Código fuente de C ++ que debe ser preprocesado. Tenga en cuenta que en .cxx, las dos últimas letras deben ser literalmente x. Del mismo modo, .C se refiere a un capital literal C.

La solución de estos debería dejarlo con una aplicación Hello World completamente funcional, como se puede ver en la demostración aquí .


3
Tenía un profesor hace mucho tiempo, cuando quitaba los puntos de su tarea o exámenes si colocaba una barra diagonal a través de un dígito cero, ya que cero no es el conjunto nulo. Agradecería esta respuesta.
Michael Burr


13

Sus compiladores esperan ASCII , pero ese programa obviamente está escrito usando EBCDIC .


Lo último que escuché es que C ++ no especifica que los programas tienen que estar escritos en ASCII, UTF-8 o cualquier otra cosa.
Adrian Ratnapala

8

Estás intentando compilar una imagen.

Escriba lo que ha escrito en un documento llamado main.cpp, ejecute ese archivo a través de su compilador, luego ejecute el archivo de salida.


23
Verifique la fecha en su PC.
James P.

14
Jaja, pero finalmente encontré una fácil que podía responder.
Cody Gray

10
Esto es tonto. Todos sabemos que el compilador optimizaría el espacio en blanco, dejando solo espacios negros muy comprimidos, que son todos unos, y se comprimiría a un 1 binario que se devolvería como un error. El código tenía que escribirse usando blanqueamiento que se compilaría a 0 y no devolvería un error.
The Tin Man

7

Debe especificar la precisión de su salida precedida por dos puntos inmediatamente antes de la llave de cierre final . Como la salida no es numérica, la precisión es cero, por lo que necesita esto:

: 0}


5

agregar:

using namespace std;

justo después incluyen: P: D


55
Prefiero escribir stdtodo el tiempo. Me recuerda que no consiga uno.
Mateen Ulhaq


5

El problema radica en la definición de sintaxis, ¡intente usar una regla y brújulas para una descripción más clásica!

Salud,


5

Intente cambiar la interfaz de entrada. C ++ espera que se conecte un teclado a su computadora, no un escáner. Puede haber problemas de conflicto de periféricos aquí. No verifiqué en el estándar ISO si la interfaz de entrada del teclado es obligatoria, pero eso es cierto para todos los compiladores que he usado. Pero tal vez la entrada del escáner ahora esté disponible en C99, y en este caso su programa debería funcionar. Si no, tendrá que esperar la próxima versión estándar y actualización de compiladores.


5

Podrías probar diferentes colores para los corchetes, ¿quizás algo de verde o rojo ayudaría? Creo que su compilador no puede reconocer la tinta negra: P


5

¿Soy el único que no puede reconocer el carácter entre 'retorno' y el punto y coma? ¡Eso podría ser!


44
Es una letra mayúscula O con una línea especial que llamamos "diámetro", que le dice al compilador que use el algoritmo de círculo de punto medio, obviamente. Creo que deberías revisar tus ojos.
Mateen Ulhaq
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.