Mengapa program ini secara keliru ditolak oleh tiga kompiler C ++?


468

Saya mengalami kesulitan menyusun program C ++ yang saya tulis.

Program ini sangat sederhana dan, setahu saya, sesuai dengan semua aturan yang ditetapkan dalam Standar C ++. Saya sudah membaca keseluruhan ISO / IEC 14882: 2003 dua kali untuk memastikan.

Programnya adalah sebagai berikut:

masukkan deskripsi gambar di sini

Ini adalah output yang saya terima ketika mencoba mengkompilasi program ini dengan 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

Merasa cemas, saya mencoba g ++ 4.5.2, tetapi sama-sama tidak membantu:

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

Saya pikir Clang (versi 3.0 trunk 127530) harus bekerja, karena sangat dipuji karena kesesuaian standarnya. Sayangnya, itu bahkan tidak memberi saya salah satu pesan kesalahannya yang cantik dan disorot:

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)

Sejujurnya, saya tidak benar-benar tahu apa arti dari pesan kesalahan ini.

Banyak program C ++ lainnya memiliki file sumber dengan ekstensi .cpp , jadi saya pikir mungkin saya perlu mengganti nama file saya. Saya mengubah namanya menjadi helloworld.cpp , tetapi itu tidak membantu. Saya pikir ada bug yang sangat serius di Dentang karena ketika saya mencoba menggunakannya untuk mengkompilasi program yang diganti namanya, ia membalik, mencetak "84 peringatan dan 20 kesalahan yang dihasilkan." dan membuat banyak bip komputer saya!

Apa yang saya lakukan salah di sini? Apakah saya melewatkan beberapa bagian penting dari Standar C ++? Atau apakah ketiga kompiler ini benar-benar rusak sehingga mereka tidak dapat menyusun program sederhana ini?

Jawaban:


173

Dalam standar, §2.1 / 1 menetapkan:

Karakter file sumber fisik dipetakan, dengan cara yang ditentukan implementasi, ke set karakter sumber dasar (memperkenalkan karakter baris baru untuk indikator end-of-line) jika perlu.

Kompiler Anda tidak mendukung format itu (alias tidak dapat memetakannya ke set karakter sumber dasar ), sehingga tidak dapat bergerak ke tahap pemrosesan lebih lanjut, karena itu kesalahan. Sangat mungkin bahwa kompiler Anda mendukung pemetaan dari gambar ke set karakter sumber dasar, tetapi tidak diharuskan.

Karena pemetaan ini ditentukan oleh implementasi, Anda harus melihat dokumentasi implementasi Anda untuk melihat format file yang didukungnya. Biasanya, setiap vendor kompiler utama mendukung file teks (ditentukan secara kanonik): file apa pun yang dihasilkan oleh editor teks, biasanya serangkaian karakter.


Perhatikan bahwa standar C ++ didasarkan pada standar C (§1.1 / 2), dan standar C (99) mengatakan, dalam §1.2:

Standar Internasional ini tidak menentukan
- mekanisme dimana program C ditransformasikan untuk digunakan oleh sistem pemrosesan data;
- mekanisme yang digunakan program C untuk digunakan oleh sistem pemrosesan data;
- mekanisme dimana input data ditransformasikan untuk digunakan oleh program C;

Jadi, sekali lagi, perawatan file sumber adalah sesuatu yang perlu Anda temukan dalam dokumentasi kompiler Anda.


23
Saya pikir kalimat itu ambigu. Kamus Merriam-Webster mengatakan bahwa teks adalah kata dan bentuk asli dari karya tulis atau cetak atau karya yang mengandung teks tersebut . File sumber ini jelas berada di bawah definisi itu. Apakah Anda pikir saya harus mengajukan laporan cacat dengan Kelompok Kerja Bahasa Inti?
James McNellis

15
Oh Saya benar-benar lupa membaca semua dokumen yang direferensikan. Saya pikir paragraf itu diambil di luar konteks, jadi saya akan pergi dan membaca keseluruhan ISO / IEC 9899: 1990 dan akan dikirim kembali ke sini setelah saya sepenuhnya memahaminya.
James McNellis



211

Anda <dan >, (dan ), {dan }tampaknya tidak cocok dengan sangat baik; Cobalah menggambar mereka dengan lebih baik.


44
Meskipun saya tidak menghargai Anda mengolok-olok tulisan tangan saya, ini mungkin masalah sebenarnya, dan akan menjelaskan kesalahan yang saya dapatkan ketika saya mencoba mengkompilasi helloworld.cpp yang diganti nama dengan Visual C ++: "kesalahan fatal C1004: tak terduga akhir file ditemukan "Saya akan mencoba lagi dan segera melaporkan kembali. Terima kasih!
James McNellis

37
@Yames pastikan Anda mematikan semua optimasi png. itu membuat debugging lebih mudah.
wilhelmtell

5
@James: "file tak terduga" hampir pasti berarti bahwa Andalah }yang menyebabkan masalah. Coba fokus untuk mencocokkan itu dengan{
Carson63000

156

Anda dapat mencoba skrip python berikut. Perhatikan bahwa Anda perlu menginstal PIL dan pytesser .

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

Untuk menggunakannya, lakukan:

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

110

Anda lupa menggunakan Comic Sans sebagai font, itu sebabnya kesalahan.


73
Sayangnya, ini adalah satu-satunya font yang didukung oleh tangan saya. Itu akan sangat menyedihkan jika saya tidak dapat memprogram dalam C ++ karena hal ini. Apakah Anda pikir Java akan mendukung font ini?
James McNellis

8
Anda akan memerlukan Comic Sans ketika Anda berpikir untuk menggambar komik, jadi Anda harus serius mempertimbangkan untuk meningkatkan tangan.
sharptooth

8
C ++ membutuhkan pelatihan kaligrafi selama setahun. Jika Anda tidak punya waktu, coba Visual Basic atau hanya kode mesin biner (Anda hanya perlu mendapatkan 0 dan 1 saat itu).
Frank Osterfeld

1
@ Frank C ++ 0x §42.1 / 1 menetapkan "Semua string harus dalam bahasa Gothic."
Mateen Ulhaq

75

Saya tidak dapat melihat baris baru setelah penjepit terakhir.

Seperti yang Anda ketahui: "Jika file sumber yang tidak kosong tidak diakhiri dengan karakter baris baru, ... perilaku tidak terdefinisi".


16
Hmmm. Untungnya aturan konyol ini telah dihapus di C ++ 0x. Yang mengatakan, bagaimana cara mengakhiri file dengan baris baru? Saya pikir saya telah meninggalkan ruang yang cukup di akhir teks (jika Anda menyorot file sumber, Anda harus melihat ruang tambahan yang saya tinggalkan). Terima kasih atas tipnya!
James McNellis

8
Jika Anda tidak memiliki cukup spasi putih, saya dapat mencoba mengompilasinya di sistem saya. Saya memiliki empat monitor sehingga saya dapat mencoba mengkompilasi dari yang paling kiri.
the Tin Man

74

Program ini valid - saya tidak dapat menemukan kesalahan.

Dugaan saya adalah Anda memiliki virus di komputer Anda. Akan lebih baik jika Anda memformat ulang drive Anda, dan menginstal ulang sistem operasi.

Beri tahu kami cara kerjanya, atau jika Anda memerlukan bantuan untuk menginstal ulang.

Saya benci virus.


17
Ya, coba instal Linux. Saya menyalahkan Windows untuk masalah Anda.
Raedwald

62

Saya merasa terbantu untuk tidak menulis kode di kaca monitor saya dengan spidol ajaib, meskipun terlihat bagus ketika benar-benar hitam. Layar terisi terlalu cepat dan kemudian orang-orang yang memberi saya monitor bersih memanggil saya nama setiap minggu.

Beberapa karyawan saya (saya seorang manajer) menyempatkan untuk membelikan saya salah satu komputer pad merah dengan tombol-tombol. Mereka berkata bahwa saya tidak akan membutuhkan spidol dan saya dapat membersihkan layar sendiri saat penuh tetapi saya harus berhati-hati mengocoknya. Saya kira itu halus seperti itu.

Itu sebabnya saya mempekerjakan orang-orang pintar.


2
Wacom Cintiq jauh lebih tepat untuk seorang manajer. Itu mahal, dan membuat Anda merasa sangat penting. Setiap desainer grafis di perusahaan Anda akan memiliki status yang jauh lebih rendah, dan karenanya harus menggunakan monitor EGA. Petugas kebersihan harus menggunakan monitor CGA. Pemrogram harus menggunakan terminal monokrom bekas.
Steve314

7
Saya memiliki monitor "Seperti Hidup" untuk waktu yang lama. Itu sangat realistis sehingga Anda bersumpah screensaver ikan berenang itu nyata, dan penyelam kecil itu tampak seperti sedang berenang. Aku terus membasahi lenganku, berusaha mendapatkan peti harta karun dari bawah, sungguh nyata. Satu-satunya masalah adalah screen saver selalu menyala dan suara-suara menggelegar yang realistis membuatnya sulit untuk didengar. Oh, dan mereka berkata untuk pemeliharaan, saya harus memercikkan sesuatu di bagian atas monitor setiap hari atau screen saver akan berhenti bekerja. Itu melakukannya sekali, dan bocah, bau dua hari kemudian benar-benar realistis.
the Tin Man

59

File format not recognizedAnda perlu memformat file Anda dengan benar. Itu berarti menggunakan warna dan font yang tepat untuk kode Anda. Lihat dokumentasi spesifik untuk setiap kompiler karena warna-warna ini berbeda di antara kompiler;)


14
Oh, itu masuk akal ... Saya punya sekotak 96 krayon, jadi saya yakin saya memiliki warna latar depan yang benar. Saya akan mengambil beberapa kertas konstruksi berwarna besok dan mencobanya pada kertas warna berbeda.
James McNellis

3
Untuk amannya, Anda lebih baik mendapatkan pensil pewarna dan cat berbasis minyak juga. Ini adalah fakta yang diketahui bahwa C ++ dimaksudkan untuk menjadi bahasa yang sangat sulit untuk diformat dengan benar.
helloworld922

Ya, dan jangan lupa untuk menggunakan penanda sorotan.
sharptooth

6
@sharptooth - penyorotan sintaks adalah fitur IDE - Anda tidak seharusnya melakukannya dengan tangan. Jadi, pastikan Anda mendapatkan lengan robot untuk pergi dengan penanda sorot itu.
Steve314

56

Anda lupa pra-prosesor. Coba ini:

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

8
Oh! Saya pikir preprocessor disertakan dengan kompiler! Saya akan mencoba mencari preprosesor yang berfungsi pada laptop Windows saya.
James McNellis

3
@ James McNellis: Preprocessor bukan sebuah program, ini adalah perangkat keras yang terlihat seperti penanda penyorotan - Anda memindahkannya ke teks Anda dan menjadi preprocessed.
sharptooth

49

Apakah Anda menulis sendiri program tersebut dan kemudian memindai ke dalam komputer? Itulah yang tersirat oleh "helloworld.png". Jika itu masalahnya, Anda perlu menyadari bahwa standar C ++ (bahkan dalam edisi terbarunya) tidak memerlukan kehadiran pengenalan karakter optik, dan sayangnya itu tidak dimasukkan sebagai fitur opsional dalam kompiler saat ini.

Anda mungkin ingin mempertimbangkan untuk memindahkan gambar ke format teks. Editor teks biasa dapat digunakan; penggunaan pengolah kata, walaupun mampu menghasilkan hasil cetakan yang cantik, kemungkinan besar akan menghasilkan kesalahan yang sama dengan yang Anda dapatkan saat mencoba memindai.

Jika Anda benar-benar suka bertualang, Anda dapat mencoba untuk menulis kode Anda ke dalam pengolah kata. Cetak, sebaiknya gunakan font seperti OCR-A . Kemudian, ambil cetakan Anda dan pindai kembali. Pemindaian kemudian dapat dijalankan melalui paket OCR pihak ketiga untuk menghasilkan formulir teks. Bentuk teks kemudian dapat dikompilasi menggunakan salah satu dari banyak kompiler standar.

Namun waspadalah terhadap besarnya biaya kertas yang akan ditimbulkan selama fase debugging.


Dilema ayam & telur: Apakah mungkin untuk menulis kode C ++ untuk perangkat lunak OCR dan mengompilasinya tanpa OCR?
jweyrich

5
Ya, Anda menggunakan perakitan untuk OCR asli.
Kevin Lacquement

@ jweyrich - Saya pikir Anda harus mendapatkan bootstrap C ++ / OCR Anda dengan asm / OCR toolchain Anda terlebih dahulu.
Michael Burr


46

Gambar menyertakan di bawah ini untuk membuatnya dikompilasi:

#include <ChuckNorris>

Saya dengar dia bisa mengompilasi kesalahan sintaks ...


46
Saya pribadi lebih suka #include <JonSkeet>.
Icode4food

40

Sayangnya, Anda telah memilih tiga kompiler yang semuanya mendukung banyak bahasa, bukan hanya C ++. Mereka semua harus menebak bahasa pemrograman yang Anda gunakan. Seperti yang mungkin sudah Anda ketahui, format PNG cocok untuk semua bahasa pemrograman, bukan hanya C ++.

Biasanya kompiler dapat mengetahui bahasa itu sendiri. Sebagai contoh, jika PNG jelas digambar dengan krayon, kompiler akan tahu itu berisi Visual Basic. Jika sepertinya digambar dengan pensil mekanik, mudah mengenali insinyur di tempat kerja, menulis kode FORTRAN.

Langkah kedua ini juga tidak membantu kompiler, dalam hal ini. C dan C ++ hanya terlihat terlalu mirip, sampai ke #include. Oleh karena itu, Anda harus membantu kompilator memutuskan bahasa apa itu sebenarnya. Sekarang, Anda bisa menggunakan cara yang tidak standar. Misalnya, kompiler Visual Studio menerima argumen baris perintah / TC dan / TP , atau Anda bisa menggunakan opsi "Kompilasi sebagai: C ++" dalam file proyek. GCC dan Dentang memiliki mekanisme sendiri, yang saya tidak tahu.

Oleh karena itu, saya akan merekomendasikan menggunakan metode standar untuk memberi tahu kompiler Anda bahwa kode berikut dalam C ++. Seperti yang sudah Anda temukan sekarang, kompiler C ++ sangat pilih-pilih tentang apa yang mereka terima. Oleh karena itu cara standar untuk mengidentifikasi C ++ adalah dengan menambahkan programmer intimidasi ke kode C ++ mereka. Sebagai contoh, baris berikut akan mengklarifikasi kepada kompiler Anda bahwa yang berikut adalah C ++ (dan dia lebih baik mengkompilasinya tanpa keluhan).

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

10
Saya pikir #pragmaitu cara yang benar untuk "mendapatkan pesan" ke kompiler?
Imamat Uskup

33

Coba yang ini:

Apakah Anda melihat dinosaurus di pesawat ulang-alik?


4
Saya pikir ada kesalahan ketik - seharusnya endl(L) bukan end1(satu). Tapi +1 dilakukan dengan baik!
Rup

44
Saya sudah menatap ini selama tiga jam tapi saya masih tidak bisa melihat dinosaurus atau pesawat ulang-alik. :-(
oosterwal

32

Apakah kompiler Anda disetel dalam mode pakar ?! Jika ya, seharusnya tidak dikompilasi. Kompiler modern sudah bosan dengan "Hello World!"


27

OCR Berkata:

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

Sangat bagus, untuk bersikap adil.


4
Wow, OCR telah membaik sejak saya mencoba memindai tulisan tangan saya (menghabiskan berjam-jam menulisnya juga).
James P.

40
Saya pikir kita perlu menambahkan tag Perl.
MSalters

26

helloworld.png: file tidak dikenali: Format file tidak dikenali

Jelas, Anda harus memformat hard drive Anda.

Sungguh, kesalahan ini tidak terlalu sulit untuk dibaca.


20

Saya telah mengubah program Anda dari PNG ke ASCII, tetapi belum dikompilasi. Sekadar informasi, saya memang mencoba dengan lebar garis 100 dan 250 karakter tetapi keduanya menghasilkan hasil yang sebanding.

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

8
Anda mungkin harus menggunakan 80 atau bahkan 72 kolom sebagai gantinya
Tobias Kienzler

16

Masalah pertama adalah, Anda mencoba mengembalikan nilai yang salah di akhir fungsi utama. Standar C ++ menentukan bahwa tipe pengembalian main () adalah int, tetapi Anda mencoba mengembalikan set kosong.

Masalah lainnya adalah - setidaknya dengan g ++ - bahwa kompiler menyimpulkan bahasa yang digunakan dari akhiran file. Dari g ++ (1):

Untuk setiap file input yang diberikan, akhiran nama file menentukan jenis kompilasi yang dilakukan:

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

Kode sumber C ++ yang harus diproses terlebih dahulu. Perhatikan bahwa dalam .cxx, dua huruf terakhir harus keduanya benar-benar x. Demikian juga, .C mengacu pada modal literal C.

Memperbaiki ini akan meninggalkan Anda dengan aplikasi Hello World yang berfungsi penuh, seperti dapat dilihat dari demo di sini .


3
Saya memiliki seorang profesor saat ketika siapa yang akan mengambil poin pekerjaan rumah atau ujian Anda jika Anda memotong angka nol karena nol bukan nol. Dia akan menghargai jawaban ini.
Michael Burr


13

Kompiler Anda mengharapkan ASCII , tetapi program itu jelas ditulis menggunakan EBCDIC .


Terakhir saya dengar C ++ tidak menentukan bahwa program harus ditulis dalam ASCII, UTF-8 atau yang lainnya.
Adrian Ratnapala

8

Anda mencoba mengompilasi gambar.

Ketik apa yang Anda tulis ke dalam dokumen bernama main.cpp, jalankan file itu melalui kompiler Anda, kemudian jalankan file output.


23
Periksa tanggal di PC Anda.
James P.

14
Haha, tetapi akhirnya saya menemukan yang mudah yang bisa saya jawab!
Cody Grey

10
Ini konyol. Kita semua tahu kompiler akan mengoptimalkan spasi, hanya menyisakan ruang hitam yang terkompresi, yang semuanya dan akan dikompres ke biner 1 yang akan dikembalikan sebagai kesalahan. Kode harus ditulis menggunakan white-out yang akan dikompilasi ke 0 dan tidak mengembalikan kesalahan.
the Tin Man

7

Anda perlu menentukan ketepatan hasil Anda didahului dengan tanda titik dua sesaat sebelum penjepit penutup akhir . Karena outputnya tidak numerik, presisinya nol, jadi Anda perlu ini-

: 0}


5

Menambahkan :

using namespace std;

tepat setelah termasuk: P: D


5
Saya lebih suka mengetik stdsepanjang waktu. Mengingatkan saya untuk tidak mendapatkannya.
Mateen Ulhaq


5

Masalahnya terletak pada definisi sintaksis, coba gunakan penggaris dan kompas untuk deskripsi yang lebih klasik!

Bersulang,


5

Coba alihkan antarmuka input. C ++ mengharapkan keyboard dicolokkan ke komputer Anda, bukan pemindai. Mungkin ada masalah konflik periferal di sini. Saya tidak memeriksa dalam ISO Standard jika antarmuka input keyboard adalah wajib, tetapi itu berlaku untuk semua kompiler yang pernah saya gunakan. Tapi mungkin input pemindai sekarang tersedia di C99, dan dalam hal ini program Anda memang harus bekerja. Jika tidak, Anda harus menunggu rilis standar berikutnya dan meningkatkan kompiler.


5

Anda dapat mencoba berbagai warna untuk tanda kurung, mungkin beberapa hijau atau merah akan membantu? Saya pikir kompiler Anda tidak dapat mengenali tinta hitam: P


5

Apakah saya satu-satunya yang tidak bisa mengenali karakter antara 'kembali' dan titik koma? Itu mungkin saja!


4
Ini adalah huruf kapital O dengan garis khusus yang kita sebut "diameter", yang memberitahu kompiler untuk menggunakan Algoritma Lingkaran Midpoint, jelas. Saya pikir Anda harus memeriksakan mata Anda.
Mateen Ulhaq
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.