Por que esse programa é erroneamente rejeitado por três compiladores C ++?


468

Estou com dificuldades para compilar um programa C ++ que escrevi.

Este programa é muito simples e, dentro do meu conhecimento, está em conformidade com todas as regras estabelecidas no Padrão C ++. Eu li toda a ISO / IEC 14882: 2003 duas vezes para ter certeza.

O programa é o seguinte:

insira a descrição da imagem aqui

Aqui está a saída que recebi ao tentar compilar este programa com o 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

Desanimado, tentei o g ++ 4.5.2, mas foi igualmente inútil:

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

Imaginei que o Clang (versão 3.0 tronco 127530) deve funcionar, pois é muito elogiado por sua conformidade com os padrões. Infelizmente, ele nem me deu uma de suas bonitas mensagens de erro destacadas:

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 sincero, não sei realmente o que significa qualquer uma dessas mensagens de erro.

Muitos outros programas em C ++ têm arquivos de origem com uma extensão .cpp , então pensei que talvez fosse necessário renomear meu arquivo. Mudei o nome para helloworld.cpp , mas isso não ajudou. Acho que existe um bug muito sério no Clang porque, quando tentei usá-lo para compilar o programa renomeado, ele virou, imprimiu "84 avisos e 20 erros gerados". e fiz meu computador emitir um bipe muito!

O que eu fiz de errado aqui? Perdi uma parte crítica do padrão C ++? Ou todos os três compiladores são realmente tão quebrados que não podem compilar este programa simples?

Respostas:


173

Na norma, §2.1 / 1 especifica:

Os caracteres do arquivo de origem físico são mapeados, de maneira definida pela implementação, para o conjunto de caracteres de origem básico (introdução de caracteres de nova linha para indicadores de fim de linha), se necessário.

Seu compilador não suporta esse formato (também conhecido como não pode mapeá-lo para o conjunto de caracteres de origem básico ), portanto, não pode passar para estágios de processamento adicionais, daí o erro. É perfeitamente possível que o seu compilador suporte um mapeamento da imagem para o conjunto de caracteres de origem básico, mas isso não é necessário.

Como esse mapeamento é definido pela implementação, você precisará consultar a documentação das implementações para ver os formatos de arquivo compatíveis. Normalmente, todos os principais fornecedores de compiladores oferecem suporte a arquivos de texto (definidos canonicamente): qualquer arquivo produzido por um editor de texto, geralmente uma série de caracteres.


Observe que o padrão C ++ é baseado no padrão C (§1.1 / 2), e o padrão C (99) diz, no §1.2:

Esta Norma Internacional não especifica
- o mecanismo pelo qual os programas C são transformados para uso por um sistema de processamento de dados;
- o mecanismo pelo qual os programas C são invocados para uso por um sistema de processamento de dados;
- o mecanismo pelo qual os dados de entrada são transformados para uso por um programa C;

Portanto, novamente, o tratamento dos arquivos de origem é algo que você precisa encontrar na documentação dos compiladores.


23
Eu acho que essa frase é ambígua na melhor das hipóteses. O dicionário Merriam-Webster diz que o texto é a forma e as palavras originais de uma obra escrita ou impressa ou de uma obra que contenha esse texto . Esse arquivo de origem claramente se enquadra nessa definição. Você acha que eu deveria registrar um relatório de defeitos no Grupo de Trabalho de Idiomas Principais?
James McNellis

15
Oh; Esqueci completamente de ler todos os documentos referenciados. Eu acho que esse parágrafo é retirado de contexto, portanto, irei ler a totalidade da ISO / IEC 9899: 1990 e postarei aqui uma vez que eu o compreenda completamente.
James McNellis



211

Seu <e >, (e ), {e }não parecem combinar muito bem; Tente desenhá-los melhor.


44
Embora eu não goste de você tirar sarro da minha caligrafia, esse pode ser o problema real e explicaria o erro que eu recebo ao tentar compilar o renomeado helloworld.cpp com o Visual C ++: "erro fatal C1004: final de operação inesperado arquivo encontrado "Vou tentar novamente e informar em breve. Obrigado!
James McNellis

37
@ James certifique-se de desativar todas as otimizações png. facilita a depuração.
Wilhelmtell

5
@ James: "final de arquivo inesperado" quase certamente significa que é você }quem está causando o problema. Tente se concentrar em combinar isso com o{
Carson63000

156

Você pode tentar o seguinte script python. Observe que você precisa instalar o PIL e o 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 usá-lo, faça:

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

110

Você esqueceu de usar o Comic Sans como uma fonte, por isso está errado.


73
Infelizmente, essa é a única fonte que minha mão suporta. Isso seria muito triste se eu não conseguir programar em C ++ por causa disso. Você acha que o Java suportaria essa fonte?
James McNellis

8
Você precisará do Comic Sans quando pensar em desenhar quadrinhos, então considere seriamente melhorar as mãos.
Sharptooth

8
C ++ requer treinamento de um ano em caligrafia. Se você não tiver tempo, tente o Visual Basic ou apenas o código da máquina binária (você só precisa obter os zeros e zeros).
Frank Osterfeld

1
@Frank C ++ 0x §42.1 / 1 especifica "Todas as strings devem estar em gótico".
Mateen Ulhaq

75

Não consigo ver uma nova linha depois dessa última chave.

Como você sabe: "Se um arquivo de origem que não estiver vazio não terminar com um caractere de nova linha, ... o comportamento será indefinido".


16
Hummm. Felizmente, essa regra ridícula foi removida no C ++ 0x. Dito isto, como alguém termina um arquivo com uma nova linha? Eu pensei que havia deixado espaço suficiente no final do texto (se você destacar o arquivo de origem, deverá ver o espaço extra que me resta). Obrigado pela dica, no entanto!
James McNellis

8
Se você não tiver espaço em branco suficiente, posso tentar compilá-lo no meu sistema. Eu tenho quatro monitores para tentar compilar a partir do meu mais à esquerda.
the Tin Man

74

Este programa é válido - não encontro erros.

Meu palpite é que você tem um vírus em sua máquina. Seria melhor se você reformatasse sua unidade e reinstale o sistema operacional.

Deixe-nos saber como isso funciona ou se você precisar de ajuda com a reinstalação.

Eu odeio vírus.


17
Sim, tente instalar o Linux. Eu culpo o Windows pelo seu problema.
Raedwald

62

Descobri que é útil não escrever meu código no vidro do monitor com um marcador mágico, mesmo que pareça legal quando estiver realmente preto. A tela fica cheia muito rápido e as pessoas que me dão um monitor limpo me chamam de nomes toda semana.

Alguns dos meus funcionários (eu sou gerente) estão me ligando para comprar um daqueles computadores de almofada vermelha com os botões. Disseram que não precisarei de marcadores e que posso limpar a tela quando estiver cheia, mas tenho que ter cuidado ao agitá-la. Eu acho que é delicado assim.

É por isso que contrato pessoas inteligentes.


2
Um Wacom Cintiq é muito mais apropriado para um gerente. É caro e faz você se sentir realmente importante. Qualquer designer gráfico da sua empresa terá um status muito mais baixo e, portanto, deve usar monitores EGA. Os zeladores devem usar monitores CGA. Os programadores devem usar terminais monocromáticos em segunda mão.
Steve314

7
Eu tinha um monitor "Life Like" por um longo tempo. Era tão realista que você juraria que o protetor de tela de peixes nadadores era real, e o homenzinho mergulhador parecia estar nadando. Eu fiquei molhando meu braço tentando pegar o baú do fundo, que era tão real. O único problema era que o protetor de tela estava sempre ativado e os ruídos borbulhantes realistas dificultavam a audição. Ah, e eles disseram para manutenção que eu tinha que espalhar coisas diariamente na parte superior do monitor, ou o protetor de tela deixaria de funcionar. Ele fez isso uma vez, e garoto, o cheiro dois dias depois foi realmente realista.
the Tin Man

59

File format not recognizedVocê precisa formatar corretamente seu arquivo. Isso significa usar as cores e fontes corretas para o seu código. Consulte as documentações específicas para cada compilador, pois essas cores variam entre os compiladores;)


14
Ah, isso meio que faz sentido ... Eu tenho uma caixa de 96 lápis de cera, então tenho certeza de que tenho a cor correta do primeiro plano. Amanhã vou pegar um papel de construção colorido e experimentá-lo em uma cor de papel diferente.
James McNellis

3
Para garantir a segurança, é melhor comprar lápis de cor e tinta à base de óleo. É um fato bem conhecido que o C ++ deve ser uma linguagem muito difícil de formatar corretamente.
Helloworld922

Sim, e não se esqueça de usar o marcador de destaque.
Sharptooth

6
@sharptooth - o destaque da sintaxe é um recurso do IDE - você não deve fazer isso manualmente. Portanto, certifique-se de obter um braço robótico para acompanhar esse marcador de destaque.
Steve314

56

Você esqueceu o pré-processador. Tente o seguinte:

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

8
Oh! Eu pensei que o pré-processador estava incluído no compilador! Vou tentar encontrar um pré-processador que funcione no meu laptop Windows.
James McNellis

3
@ James McNellis: O pré-processador não é um programa, é uma coisa de hardware que parece um marcador de destaque - você o move sobre o seu texto e ele é pré-processado.
Sharptooth

49

Você escreveu o programa à mão e depois o digitalizou no computador? É isso que está implícito no "helloworld.png". Se for esse o caso, você deve estar ciente de que o padrão C ++ (mesmo em sua edição mais recente) não requer a presença de reconhecimento óptico de caracteres e, infelizmente, não está incluído como um recurso opcional em nenhum compilador atual.

Você pode considerar a possibilidade de transpor os gráficos para um formato textual. Qualquer editor de texto simples pode ser usado; o uso de um processador de texto, embora capaz de gerar uma boa impressão, provavelmente resultará no mesmo erro que você recebe ao tentar digitalizar.

Se você é realmente aventureiro, pode tentar escrever seu código em um processador de texto. Imprima, de preferência usando uma fonte como OCR-A . Depois, pegue sua impressão e digitalize novamente. A digitalização pode ser executada em um pacote OCR de terceiros para gerar um formulário de texto. O formulário de texto pode ser compilado usando um dos muitos compiladores padrão.

Cuidado, no entanto, com o grande custo do papel que isso incorrerá durante a fase de depuração.


O dilema do ovo e da galinha: é possível escrever código C ++ para um software de OCR e compilá-lo sem um OCR?
jweyrich

5
Bem, você usa a montagem para o OCR original.
Kevin Lacquement

@jweyrich - Acho que você precisará inicializar seu C ++ / OCR com sua cadeia de ferramentas asm / OCR primeiro.
Michael Burr


46

Desenhe o include abaixo para compilá-lo:

#include <ChuckNorris>

Ouvi dizer que ele pode compilar erros de sintaxe ...


46
Eu pessoalmente prefiro #include <JonSkeet>.
Icode4food

40

Infelizmente, você selecionou três compiladores que suportam vários idiomas, não apenas C ++. Todos eles têm que adivinhar a linguagem de programação que você usou. Como você provavelmente já sabe, o formato PNG é adequado para todas as linguagens de programação, não apenas para C ++.

Normalmente, o compilador pode descobrir o próprio idioma. Por exemplo, se o PNG é obviamente desenhado com giz de cera, o compilador saberá que ele contém Visual Basic. Se parece que foi desenhado com uma lapiseira, é fácil reconhecer o engenheiro no trabalho, escrevendo o código FORTRAN.

Este segundo passo também não ajuda o compilador, neste caso. C e C ++ parecem muito semelhantes, até o #include. Portanto, você deve ajudar o compilador a decidir qual idioma ele realmente é. Agora, você pode usar meios não padronizados. Por exemplo, o compilador do Visual Studio aceita os argumentos de linha de comando / TC e / TP ou você pode usar a opção "Compilar como: C ++" no arquivo de projeto. O GCC e o CLang têm seus próprios mecanismos, que eu não conheço.

Portanto, eu recomendaria usar o método padrão para informar ao seu compilador que o código a seguir está em C ++. Como você já descobriu até agora, os compiladores C ++ são muito exigentes quanto ao que aceitam. Portanto, a maneira padrão de identificar C ++ é pela intimidação que os programadores adicionam ao código C ++. Por exemplo, a seguinte linha esclarecerá ao seu compilador que o que se segue é C ++ (e é melhor compilá-lo sem queixas).

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

10
Eu pensei que #pragmaera a maneira correta de "receber uma mensagem" para o compilador?
Lev Bishop

33

Tente este:

Você vê o dinossauro no ônibus espacial?


4
Eu acho que há um erro de digitação - deve ser endl(L) não end1(um). Mas +1 foi bem feito!
Rup

44
Estou encarando isso há três horas, mas ainda não consigo ver um dinossauro ou o ônibus espacial. :-(
oosterwal 02/04

32

O seu compilador está definido no modo especialista ?! Se sim, não deve ser compilado. Os compiladores modernos estão cansados ​​do "Hello World!"


27

O OCR diz:

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

O que é muito bom, para ser justo.


4
Uau, o OCR melhorou desde que tentei digitalizar minha letra (passei horas escrevendo também).
James P.

40
Eu acho que precisamos adicionar uma tag Perl.
MSalters

26

helloworld.png: arquivo não reconhecido: formato de arquivo não reconhecido

Obviamente, você deve formatar seu disco rígido.

Realmente, esses erros não são tão difíceis de ler.


20

Eu converti seu programa de PNG para ASCII, mas ele ainda não é compilado. Para sua informação, tentei com largura de linha de 100 e 250 caracteres, mas ambos produzem resultados comparáveis.

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

8
Você provavelmente deve usar 80 ou mesmo 72 colunas em vez
Tobias KIENZLER

16

O primeiro problema é que você está tentando retornar um valor incorreto no final da função principal. O padrão C ++ determina que o tipo de retorno main () é int, mas você está tentando retornar o conjunto vazio.

O outro problema é - pelo menos com o g ++ - que o compilador deduz a linguagem usada no sufixo do arquivo. Do g ++ (1):

Para qualquer arquivo de entrada, o sufixo do nome do arquivo determina que tipo de compilação é feita:

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

Código fonte C ++ que deve ser pré-processado. Observe que em .cxx, as duas últimas letras devem ser literalmente x. Da mesma forma, .C refere-se a um capital literal C.

A correção desses itens deixará você com um aplicativo Hello World totalmente funcional, como pode ser visto na demonstração aqui .


3
Eu tinha um professor há muito tempo, quando quem decolaria aponta sua lição de casa ou exames se você colocar uma barra em um dígito zero, já que zero não é o conjunto nulo. Ele apreciaria esta resposta.
Michael Burr


13

Seus compiladores estão esperando ASCII , mas esse programa é obviamente escrito usando EBCDIC .


A última vez que ouvi falar de C ++ não especifica que os programas devem ser escritos em ASCII, UTF-8 ou qualquer outra coisa.
Adrian Ratnapala

8

Você está tentando compilar uma imagem.

Digite o que você escreveu manualmente em um documento chamado main.cpp, execute esse arquivo no seu compilador e, em seguida, execute o arquivo de saída.


23
Verifique a data no seu PC.
James P.

14
Haha, mas finalmente achei uma pergunta fácil que eu poderia responder!
Cody Gray

10
Isso é bobo. Todos nós sabemos que o compilador otimizaria o espaço em branco, deixando apenas espaço em preto fortemente compactado, que é tudo e compactaria para um 1 binário que seria retornado como um erro. O código precisava ser escrito usando o branco que seria compilado para 0 e não retornaria um erro.
the Tin Man

7

Você precisa especificar a precisão de sua saída precedida por dois pontos imediatamente antes da chave de fechamento final . Como a saída não é numérica, a precisão é zero, então você precisa disso:

: 0}


5

adicionar :

using namespace std;

logo após incluem: P: D


5
Eu prefiro digitar stdo tempo todo. Lembra-me de não conseguir um.
Mateen Ulhaq


5

O problema está na definição de sintaxe, tente usar régua e bússolas para obter uma descrição mais clássica!

Felicidades,


5

Tente mudar a interface de entrada. O C ++ espera que um teclado seja conectado ao seu computador, não um scanner. Pode haver problemas de conflito de periféricos aqui. Não verifiquei o ISO Standard se a interface de entrada do teclado é obrigatória, mas isso é verdade para todos os compiladores que já usei. Mas talvez a entrada do scanner esteja agora disponível no C99 e, nesse caso, seu programa realmente funcione. Caso contrário, você terá que esperar a próxima versão padrão e atualização dos compiladores.


5

Você poderia tentar cores diferentes entre parênteses, talvez um pouco de verde ou vermelho ajudasse? Eu acho que seu compilador não pode reconhecer tinta preta: P


5

Eu sou o único que não consegue reconhecer o personagem entre 'retorno' e o ponto e vírgula? Pode ser isso!


4
É uma letra maiúscula O com uma linha especial que chamamos de "diâmetro", que diz ao compilador para usar o Algoritmo do Círculo do Ponto Médio, obviamente. Eu acho que você deveria ver seus olhos.
Mateen Ulhaq
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.