Чому три компілятори 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 ++? Або всі три компілятори насправді настільки зламані, що не можуть скласти цю просту програму?

Відповіді:


173

У стандарті §2.1 / 1 визначено:

Символи файлів фізичного джерела відображаються у визначеному реалізацією порядку до основного набору символів вихідного коду (вводячи нові символи для індикаторів кінця рядка), якщо це необхідно.

Ваш компілятор не підтримує цей формат (він також не може відобразити його до основного набору символів джерела ), тому він не може перейти на подальші етапи обробки, отже, помилка. Цілком можливо, що ваш компілятор підтримує відображення від зображення до основного набору символів, але цього не потрібно.

Оскільки це відображення визначено реалізацією, вам потрібно переглянути документацію щодо їх реалізації, щоб побачити формати файлів, які він підтримує. Як правило, кожен великий постачальник компілятора підтримує текстові файли (визначені канонічно): будь-який файл, створений текстовим редактором, як правило, серія символів.


Зауважте, що стандарт C ++ базується на стандарті C (§1.1 / 2), а стандарт C (99) говориться в §1.2:

Цей Міжнародний стандарт не визначає
- механізм, за допомогою якого програми C трансформуються для використання системою обробки даних;
- механізм, за допомогою якого програми C викликаються для використання системою обробки даних;
- механізм, за допомогою якого перетворюються вхідні дані для використання програмою С;

Отже, знову-таки обробка вихідних файлів - це те, що вам потрібно знайти в документації на компілятори.


23
Я вважаю, що вирок у кращому випадку неоднозначний. Словник Merriam-Webster говорить, що текст - це оригінальні слова та форма написаного чи друкованого твору або твір, що містить такий текст . Цей вихідний файл явно підпадає під таке визначення. Як ви вважаєте, я повинен подати звіт про дефекти до робочої групи з основних мов?
Джеймс Мак-Нілліс

15
Ой; Я повністю забув прочитати всі посилаються документи. Я думаю, що цей параграф виведений із контексту, тому я піду прочитати всю ISO / IEC 9899: 1990 і опублікую тут, коли я повністю зрозумію це.
Джеймс Мак-Нілліс

575

Родом із Overv @ reddit .


19
Найкраще. Формат BMP. Ілюстрація специфікації. Колись.
Тобіас Кіенцлер

49
Тож помилка ОП полягала у використанні png замість bmp?
підрозділ

1
Надихнувшись цією прекрасною відповіддю, я вирішив зробити щось подібне для brainf ***: blog.dreasgrech.com/2011/04/…
Andreas


211

Ваш <і >, (і ), {і , }здається, не дуже добре підходять; Спробуйте намалювати їх краще.


44
Хоча я не вдячний, що ти знущаєшся над моїм почерком, це може бути справжньою проблемою, і я пояснив би помилку, яку я отримую, коли намагаюся скласти перейменований helloworld.cpp з Visual C ++: "фатальна помилка C1004: несподіваний кінець- файл знайдений "Я спробую ще раз і незабаром звітую. Дякую!
Джеймс Мак-Нілліс

37
@James переконайтеся, що ви вимкнено всі оптимізації в форматі png. це полегшує налагодження.
wilhelmtell

5
@James: "несподіваний кінець файлу" майже напевно означає, що саме }це викликає проблему. Спробуйте зосередитись на тому, щоб відповідати цьому{
Carson63000,

156

Ви можете спробувати наступний скрипт python. Зауважте, що вам потрібно встановити PIL та пітессер .

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 підтримувала б цей шрифт?
Джеймс Мак-Нілліс

8
Comic Sans вам знадобляться, коли ви все-таки думаєте малювати комікси, тож варто серйозно задуматися над оновленням рук.
різкозуб

8
C ++ вимагає річної підготовки з каліграфії. Якщо у вас немає часу, спробуйте Visual Basic або просто двійковий машинний код (Ви просто повинні отримати 0 та 1 тоді).
Френк Остерфельд

1
@Frank C ++ 0x §42.1 / 1 вказує "Усі рядки повинні бути готичними."
Mateen Ulhaq

75

Я не бачу нового рядка після останньої дужки.

Як відомо: "Якщо вихідний файл, який не є порожнім, не закінчується символом нового рядка, ... поведінка не визначена".


16
Хммм. На щастя, це смішне правило було видалено в C ++ 0x. Це означає, як можна закінчити такий файл новим рядком? Я подумав, що залишив достатньо місця в кінці тексту (якщо ви виділите вихідний файл, ви повинні побачити додаткову кімнату, яку я залишив). Дякую за пораду, хоча!
Джеймс Мак-Нілліс

8
Якщо у вас недостатньо пробілу, я можу спробувати скласти його в моїй системі. У мене є чотири монітори, тому я можу спробувати скласти з мого крайнього лівого.
Людина з жерсті

74

Ця програма дійсна - я не можу знайти помилок.

Я здогадуюсь, у вас на вірусі є вірус. Найкраще буде переформатувати накопичувач і перевстановити операційну систему.

Повідомте нас, як це працює, або якщо вам потрібна допомога з перевстановленням.

Я ненавиджу віруси.


17
Так, спробуйте встановити Linux. Я звинувачую Windows у вашій проблемі.
Raedwald

62

Я виявив, що це допомагає не писати свій код на склі монітора за допомогою магічного маркера, навіть якщо це виглядає приємно, коли він справді чорний. Екран заповнюється занадто швидко, і тоді люди, які дають мені чистий монітор, називають мене іменами щотижня.

Пару моїх співробітників (я менеджер) збираються, щоб купити мені один із тих червоних комп'ютерів з килимами. Вони сказали, що маркери мені не знадобляться, і я можу самостійно почистити екран, коли він заповнений, але я мушу бути обережно струшуючи його. Я гадав, що це делікатно.

Тому я наймаю розумних людей.


2
Wacom Cintiq набагато підходить менеджеру. Це дорого і змушує почувати себе справді важливим. Будь-які графічні дизайнери у вашій компанії матимуть значно нижчий статус, і тому вони повинні використовувати монітори EGA. Двірники повинні використовувати монітори CGA. Програмісти повинні використовувати однотонні термінали б / у.
Steve314

7
Я довго мав монітор "Життя як". Це було так реалістично, що ви б поклялися, що заставка плаваючої риби була справжньою, а маленький водолаз виглядав так, ніби він плавав. Я продовжував мочити руку, намагаючись дістати скриню зі скарбами знизу, це було так реально. Єдина проблема полягала в тому, що заставка завжди була ввімкнена, а реалістичні гучні звуки важко чути. О, і вони сказали, що для обслуговування я повинен щодня посипати речі у верхній частині монітора, інакше заставка перестане працювати. Це було колись, і хлопче, запах через два дні був справді реалістичним.
Олов'яний чоловік

59

File format not recognizedПотрібно правильно відформатувати файл. Це означає використання правильних кольорів та шрифтів для коду. Дивіться конкретні документації для кожного компілятора, оскільки ці кольори залежать від компілятора;)


14
О, це має сенс ... У мене коробка з 96 олівцями, тож я впевнений, що я маю правильний колір переднього плану. Я завтра підберу якийсь кольоровий будівельний папір і спробую його на іншому кольорі паперу.
Джеймс Макнелліс

3
Щоб бути безпечним, краще також придбайте кольорові олівці та олійну фарбу. Загальновідомий факт, що C ++ мається на увазі дуже складна мова для правильного форматування.
helloworld922

Так, і не забудьте використовувати маркер для підсвічування.
shartooth

6
@sharptooth - підсвічування синтаксису є функцією IDE - ви не призначені для цього вручну. Тому переконайтеся, що у вас є рука роботи, яка йде з цим маркером виділення.
Steve314

56

Ви забули попередній процесор. Спробуйте це:

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

8
Ой! Я думав, що препроцесор був включений до компілятора! Я спробую знайти препроцесора, який працює на моєму ноутбуці Windows.
James McNellis

3
@James McNellis: Препроцесор - це не програма, це апаратна річ, схожа на маркер виділення - ви переміщуєте її над текстом, і він стає попередньо обробленим.
гострий зуб

49

Ви написали програму, а потім сканували її в комп'ютер? Саме це мається на увазі під "helloworld.png". Якщо це так, вам потрібно знати, що стандарт C ++ (навіть у новітньому виданні) не вимагає наявності оптичного розпізнавання символів, і, на жаль, він не включений як додаткова функція в жоден поточний компілятор.

Ви можете розглянути можливість перенесення графіки у текстовий формат. Може використовуватися будь-який текстовий редактор; використання текстового процесора, здатне генерувати досить роздруківку, швидше за все, призведе до тієї ж помилки, яку ви отримаєте при спробі сканування.

Якщо ви справді авантюрні, ви можете спробувати написати свій код у текстовому процесорі. Роздрукуйте його, бажано, використовуючи шрифт типу OCR-A . Потім візьміть роздруківку і скануйте її назад. Потім сканування можна запустити через сторонній пакет OCR для створення текстової форми. Текстова форма може бути складена за допомогою одного з багатьох стандартних компіляторів.

Остерігайтеся, однак, великих витрат паперу, які виникнуть в процесі налагодження.


Дилема з куркою та яйцем: чи можна написати C ++ код для програм OCR та компілювати його без OCR?
jweyrich

5
Ну, так, ви використовуєте збірку для оригінального OCR.
Кевін Лакімент

@jweyrich - Я думаю, вам спочатку потрібно отримати завантаження C ++ / OCR за допомогою вашої ланцюжка інструментів asm / OCR.
Майкл Берр

2

46

Намалюйте включити нижче, щоб зробити його компільованим:

#include <ChuckNorris>

Я чую, що він може компілювати синтаксичні помилки ...


46
Я особисто віддаю перевагу #include <JonSkeet>.
Icode4food

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це правильний спосіб "отримати повідомлення" компілятору?
Левський єпископ

33

Спробуйте це:

Ви бачите динозавра в космічному човні?


4
Я думаю, що є помилка друку - вона повинна бути endl(L) не end1(одна). Але +1 прекрасно зроблено!
Rup

44
Я дивився на це три години, але все ще не бачу динозавра або космічного човника. :-(
oosterwal

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 покращився, оскільки я спробував сканувати свій почерк (витрачав години на його написання теж).
Джеймс П.

40
Я думаю, нам потрібно додати тег Perl.
MSalters

26

helloworld.png: файл не впізнано: формат файлу не розпізнаний

Очевидно, ви повинні відформатувати ваш жорсткий диск.

Дійсно, ці помилки не так важко читати.


20

Я перетворив вашу програму з PNG в ASCII, але вона ще не компілюється. Для вашої інформації, я намагався з шириною рядка 100 та 250 символів, але обидва отримують порівнянні результати.

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

8
Напевно, ви повинні використовувати замість 80 або навіть 72 колонки
Тобіас Кіенцлер

16

Перша проблема полягає в тому, що ви намагаєтесь повернути неправильне значення в кінці основної функції. Стандарт 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
У мене був професор назад, коли хто би знімав очки з домашнього завдання або іспитів, якщо ви поставили косу рису через нульову цифру, оскільки нуль не є нульовим набором. Він би вдячний за цю відповідь.
Майкл Берр


13

Ваші компілятори очікують ASCII , але ця програма, очевидно, написана за допомогою EBCDIC .


Востаннє я чув, що C ++ не вказує на те, що програми повинні бути записані в ASCII, UTF-8 або що-небудь ще.
Адріан Ратнапала

8

Ви намагаєтеся скласти зображення.

Введіть те, що ви написали вручну в документі під назвою main.cpp, запустіть цей файл через компілятор, а потім запустіть вихідний файл.


23
Перевірте дату на своєму ПК.
Джеймс П.

14
Ха-ха, але я нарешті знайшов легкий, на який я міг відповісти!
Коді Грей

10
Це нерозумно. Ми всі знаємо, що компілятор оптимізував би пробіл, залишаючи лише сильно стиснений чорний простір, який є всіма, і стиснеться до двійкового 1, який буде повернуто як помилка. Код потрібно писати за допомогою побілки, яка складе 0 і не поверне помилку.
Олов'яний чоловік

7

Вам потрібно вказати точність виводу, перед якою ставиться двокрапка безпосередньо перед кінцевою дужкою закриття . Оскільки вихід не є числовим, точність дорівнює нулю, тому вам потрібно це-

: 0}


5

додати:

using namespace std;

відразу після включення: P: D


5
Я вважаю за краще stdвесь час вводити текст . Нагадує мені не дістати.
Mateen Ulhaq


5

Проблема полягає у визначенні синтаксису, спробуйте використовувати лінійку та компаси для більш класичного опису!

Ура,


5

Спробуйте переключити вхідний інтерфейс. C ++ очікує, що до комп'ютера буде підключена клавіатура, а не сканер. Тут можуть виникнути проблеми конфлікту периферійних пристроїв. Я не перевірив стандарт ISO, чи інтерфейс введення клавіатури є обов'язковим, але це справедливо для всіх компіляторів, які я коли-небудь використовував. Але, можливо, вхід сканера тепер доступний в C99, і в цьому випадку ваша програма дійсно повинна працювати. Якщо ні, то вам доведеться чекати наступного стандартного випуску та оновлення компіляторів.


5

Ви можете спробувати різні кольори для дужок, може, допоможе якийсь зелений чи червоний? Я думаю, що ваш компілятор не може визнати чорну фарбу: P


5

Я єдиний, хто не може розпізнати символ між «поверненням» та крапкою з комою? Це могло бути!


4
Це велика літера O зі спеціальним рядком, який ми називаємо "діаметром", який говорить компілятору використовувати алгоритм кола Midpoint Circle, очевидно. Я думаю, вам слід перевірити очі.
Mateen Ulhaq
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.