STRING dan UNSTRING

Perakitan beberapa field menjadi satu teks dan pemecahan teks berdasarkan pembatas.

Daftar isi

STRING merakit beberapa field sumber menjadi satu teks utuh, sedangkan UNSTRING memecah satu teks menjadi beberapa field menurut pembatas yang ditentukan. Topik ini membahas pembatasan sumber dengan DELIMITED BY, pengendalian posisi tulis dengan WITH POINTER, penanganan meluap dengan ON OVERFLOW, serta penghitungan field hasil UNSTRING dengan TALLYING IN. Dua aturan yang menyertai keduanya adalah pembersihan field tujuan dan inisialisasi pointer sebelum pernyataan dijalankan.

Merakit teks dengan STRING#

Pernyataan STRING menyalin sumber-sumbernya secara berurutan ke satu field tujuan, dan kata DELIMITED BY menentukan bagian dari setiap sumber yang dikirim. Bentuk DELIMITED BY SIZE mengirim seluruh field termasuk spasi pengisinya, sedangkan DELIMITED BY SPACE mengirim sampai spasi pertama sehingga pengisi terbuang.

Bentuk DELIMITED BYBagian sumber yang dikirim
SIZESeluruh isi field, termasuk spasi pengisi
SPACESampai spasi pertama, tanpa spasi pengisi

Pemisah antarsumber tidak pernah ditambahkan secara otomatis, sehingga spasi antarfield dikirim sebagai sumber tersendiri dengan DELIMITED BY SIZE. Pointer pada WITH POINTER menentukan posisi awal penulisan dan wajib berada di dalam rentang field, sehingga diisi dengan VALUE 1 pada deklarasi atau dengan MOVE 1 sebelum pernyataan dijalankan. Program berikut merakit nama lengkap dari tiga field, lalu memperlihatkan akibat STRING yang dijalankan tanpa pembersihan tujuan.

cobol rakit-nama.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. RAKIT-NAMA.
      *--------------------------------------------------------------
      * STRING: merakit nama lengkap dari tiga field terpisah.
      *--------------------------------------------------------------
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 NAMA-DEPAN    PIC X(8) VALUE "Dewi".
       01 NAMA-TENGAH   PIC X(8) VALUE "Lestari".
       01 NAMA-BELAKANG PIC X(8) VALUE "Nugraha".
       01 NAMA-LENGKAP  PIC X(24).
       01 POSISI        PIC 9(2) VALUE 1.
       PROCEDURE DIVISION.
       UTAMA.
           MOVE SPACES TO NAMA-LENGKAP
           STRING NAMA-DEPAN    DELIMITED BY SPACE
                  SPACES        DELIMITED BY SIZE
                  NAMA-TENGAH   DELIMITED BY SPACE
                  SPACES        DELIMITED BY SIZE
                  NAMA-BELAKANG DELIMITED BY SPACE
                  INTO NAMA-LENGKAP
                  WITH POINTER POSISI
           END-STRING
           DISPLAY "Rakit     : [" NAMA-LENGKAP "]"
           DISPLAY "Posisi    : " POSISI
           STRING "Ali" DELIMITED BY SIZE
               INTO NAMA-LENGKAP
           END-STRING
           DISPLAY "Tanpa nol : [" NAMA-LENGKAP "]"
           MOVE SPACES TO NAMA-LENGKAP
           STRING "Ali" DELIMITED BY SIZE
               INTO NAMA-LENGKAP
           END-STRING
           DISPLAY "Setelah   : [" NAMA-LENGKAP "]"
           STOP RUN.
text Keluaran
Rakit     : [Dewi Lestari Nugraha    ]
Posisi    : 21
Tanpa nol : [Alii Lestari Nugraha    ]
Setelah   : [Ali                     ]

Nama lengkap tersusun dari tiga field ditambah dua spasi yang dikirim sebagai sumber tersendiri. Setelah 20 karakter terisi, POSISI berakhir di 21 karena pointer menunjuk posisi tempat karakter berikutnya akan ditulis. Baris “Tanpa nol” membuktikan bahwa tujuan tidak dibersihkan otomatis, yaitu “Ali” menimpa “Dew” pada awal field, sedangkan huruf i dari “Dewi” tetap tertinggal sehingga terbaca “Alii”. Setelah MOVE SPACES dijalankan lebih dahulu, hasilnya bersih sebagaimana baris terakhir.

Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./rakit-nama.

bash
# kompilasi program perakit nama
cobc -x rakit-nama.cbl

Meluap dan penanganan ON OVERFLOW#

STRING berhenti dan menandai kondisi meluap apabila field tujuan penuh padahal sumber masih tersisa, dan frasa ON OVERFLOW menampung kondisi itu tanpa menghentikan program. Frasa NOT ON OVERFLOW menjadi pasangannya untuk jalur yang berhasil, sedangkan END-STRING menutup pernyataan agar kedua jalur terbaca jelas. Program berikut menyalin teks sebelas karakter ke field lima karakter, lalu mengulanginya dengan teks yang muat.

cobol string-overflow.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. STRING-OVERFLOW.
      *--------------------------------------------------------------
      * STRING dengan ON OVERFLOW dan NOT ON OVERFLOW.
      *--------------------------------------------------------------
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 TEKS-TUJUAN PIC X(5).
       01 POSISI      PIC 9(2) VALUE 1.
       PROCEDURE DIVISION.
       UTAMA.
           STRING "untuk tugas" DELIMITED BY SIZE
               INTO TEKS-TUJUAN
               WITH POINTER POSISI
               ON OVERFLOW
                   DISPLAY "Meluap  : posisi berhenti di " POSISI
               NOT ON OVERFLOW
                   DISPLAY "Cukup   : posisi akhir " POSISI
           END-STRING
           DISPLAY "Tujuan  : [" TEKS-TUJUAN "]"
           MOVE SPACES TO TEKS-TUJUAN
           MOVE 1 TO POSISI
           STRING "satu" DELIMITED BY SIZE
               INTO TEKS-TUJUAN
               WITH POINTER POSISI
               ON OVERFLOW
                   DISPLAY "Meluap  : posisi berhenti di " POSISI
               NOT ON OVERFLOW
                   DISPLAY "Cukup   : posisi akhir " POSISI
           END-STRING
           DISPLAY "Tujuan  : [" TEKS-TUJUAN "]"
           STOP RUN.
text Keluaran
Meluap  : posisi berhenti di 06
Tujuan  : [untuk]
Cukup   : posisi akhir 05
Tujuan  : [satu ]

Dari sumber “untuk tugas”, hanya lima karakter “untuk” yang tertulis sebelum tujuan penuh, sehingga jalur ON OVERFLOW dijalankan dan POSISI berhenti di 06, yaitu posisi tempat karakter keenam semestinya ditulis. Penyalinan kedua menjalankan jalur NOT ON OVERFLOW dengan posisi akhir 05 karena empat karakter yang dikirim tidak melampaui lebar field. Isi field tujuan pada kedua kasus dikelilingi tanda kurung agar spasi pengisinya ikut terlihat.

Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./string-overflow.

bash
# kompilasi program uji meluap STRING
cobc -x string-overflow.cbl

Memecah teks dengan UNSTRING#

Pernyataan UNSTRING membaca field sumber dari kiri ke kanan, memotongnya pada setiap pembatas, lalu mengisi field tujuan satu per satu secara berurutan. Frasa TALLYING IN menghitung berapa field tujuan yang menerima data, WITH POINTER menentukan posisi baca, dan ON OVERFLOW tersedia apabila tujuan habis sedangkan sisa sumber masih ada. Program berikut memecah baris data 88;Citra;XI-A menjadi nilai, nama, dan kelas.

cobol pecah-baris.cbl
       IDENTIFICATION DIVISION.
       PROGRAM-ID. PECAH-BARIS.
      *--------------------------------------------------------------
      * UNSTRING: memecah baris data berpembatas titik koma.
      *--------------------------------------------------------------
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 BARIS-MENTAH PIC X(13) VALUE "88;Citra;XI-A".
       01 NILAI-UJIAN  PIC 9(3).
       01 NAMA-SISWA   PIC X(10).
       01 KELAS        PIC X(6).
       01 POSISI       PIC 9(2) VALUE 1.
       01 JML-FIELD    PIC 9(2) VALUE 0.
       PROCEDURE DIVISION.
       UTAMA.
           UNSTRING BARIS-MENTAH DELIMITED BY ";"
               INTO NILAI-UJIAN
                    NAMA-SISWA
                    KELAS
               WITH POINTER POSISI
               TALLYING IN JML-FIELD
           END-UNSTRING
           DISPLAY "Nilai  : " NILAI-UJIAN
           DISPLAY "Nama   : [" NAMA-SISWA "]"
           DISPLAY "Kelas  : [" KELAS "]"
           DISPLAY "Field  : " JML-FIELD
           DISPLAY "Posisi : " POSISI
           STOP RUN.
text Keluaran
Nilai  : 088
Nama   : [Citra     ]
Kelas  : [XI-A  ]
Field  : 03
Posisi : 14

Potongan “88” dikonversi menjadi angka saat memasuki NILAI-UJIAN sehingga tampil 088 sesuai picture 9(3), sedangkan NAMA-SISWA dan KELAS diisi sebagai teks dengan spasi pengisi yang terlihat di antara tanda kurung. Hitungan TALLYING IN bernilai 03 karena ketiga tujuan menerima data, dan POSISI berakhir di 14, yaitu tepat setelah karakter terakhir pada field sumber yang panjangnya 13 karakter. Beberapa pembatas dapat dituliskan sekaligus dengan kata OR sebagaimana contoh berikut.

cobol Contoh: dua pembatas dalam satu UNSTRING
           UNSTRING BARIS-MENTAH DELIMITED BY ";" OR ","
               INTO NILAI-UJIAN NAMA-SISWA KELAS
           END-UNSTRING

Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./pecah-baris.

bash
# kompilasi program pemecah baris berpembatas
cobc -x pecah-baris.cbl

Kesalahan umum#

  • Field tujuan tidak dibersihkan sebelum STRING. Isi lama tersisa pada posisi yang tidak ditimpa sumber baru, sebagaimana hasil “Alii” pada demo. Jalankan MOVE SPACES lebih dahulu.
  • Pointer tidak diinisialisasi. STRING membaca posisi awal dari pointer, dan pointer yang berisi nol atau nilai acak memicu error saat program berjalan. Isi dengan VALUE 1 pada deklarasi atau MOVE 1 sebelum pernyataan.
  • DELIMITED BY SPACE dipilih untuk teks yang memuat spasi di tengahnya, misalnya nama dengan gelar. Penyalinan berhenti pada spasi pertama, sehingga gunakan DELIMITED BY SIZE bila isi utuh diperlukan.
  • UNSTRING dijalankan tanpa ON OVERFLOW padahal field tujuan lebih sedikit daripada jumlah potongan. Sisa potongan dibuang tanpa pesan, sehingga TALLYING IN dan ON OVERFLOW membantu mendeteksinya.

Ringkasan#

  • STRING menyalin beberapa sumber ke satu tujuan dengan DELIMITED BY SIZE atau SPACE tanpa pemisah otomatis dan tanpa pembersihan tujuan, sehingga MOVE SPACES dan pengiriman pemisah perlu dilakukan secara eksplisit.
  • WITH POINTER menentukan dan melaporkan posisi tulis, sedangkan ON OVERFLOW dan NOT ON OVERFLOW menampung hasil yang meluap maupun yang muat.
  • UNSTRING memotong sumber pada satu atau beberapa pembatas dengan kata OR, mengisi tujuan secara berurutan, dan TALLYING IN menghitung tujuan yang terisi.
  • Pointer STRING dan UNSTRING wajib diinisialisasi sebelum pernyataan dijalankan.

Referensi#