C
Pekerjaan rumah saya adalah mengambil string dan membaginya menjadi beberapa bagian di setiap baris baru. Saya tidak tahu harus berbuat apa! Tolong bantu!
Masalah rumit untuk kelas pemrograman C awal! Pertama, Anda harus memahami beberapa dasar tentang subjek yang rumit ini.
String adalah urutan yang hanya terdiri dari karakter . Ini berarti bahwa agar programmer dapat menunjukkan hal "tidak terlihat" (itu bukan spasi, yang dianggap sebagai karakter), Anda harus menggunakan urutan karakter khusus untuk memaksudkan hal yang tidak terlihat itu.
Pada Windows , baris baru adalah urutan dua karakter dalam string: backslash dan n (atau string "\n"
)
Di Linux atau OS / X Mac , ini adalah urutan empat karakter: backslash, n, backslash, dan kemudian r: (atau "\n\r"
).
(Catatan sejarah yang menarik: pada Macintosh lama itu adalah urutan yang berbeda dari empat karakter: "\ r \ n" ... benar-benar mundur dari cara Unix melakukan sesuatu! Sejarah mengambil jalan yang aneh.)
Tampaknya Linux lebih boros daripada Windows, tetapi sebenarnya itu ide yang lebih baik untuk menggunakan urutan yang lebih lama. Karena Windows menggunakan urutan singkat seperti itu, runtime bahasa C tidak dapat mencetak huruf yang sebenarnya \n
tanpa menggunakan panggilan sistem khusus. Anda biasanya dapat melakukannya di Linux tanpa panggilan sistem (bahkan dapat mencetak \n\
atau \n\q
... apa pun kecuali \n\r
). Tetapi karena C dimaksudkan sebagai platform silang, ia memberlakukan common-denominator terendah. Jadi, Anda akan selalu melihat \n
di buku Anda.
(Catatan: Jika Anda bertanya-tanya bagaimana kita berbicara \n
tanpa mendapatkan baris baru setiap kali kita lakukan, StackOverflow ditulis hampir seluruhnya dalam HTML ... bukan C. Jadi jauh lebih modern. Banyak aspek lama dari C adalah sedang ditangani oleh hal-hal yang mungkin pernah Anda dengar, seperti CLANG dan LLVM.)
Tetapi kembali ke apa yang sedang kita kerjakan. Mari kita bayangkan sebuah string dengan tiga potong dan dua baris baru, seperti:
"foo\nbaz\nbar"
Anda dapat melihat panjang string itu adalah 3 + 2 + 3 + 2 + 3 = 13. Jadi Anda harus membuat buffer dengan panjang 13 untuk itu, dan programmer C selalu menambahkan satu ke ukuran array mereka agar aman. Jadi buat buffer Anda dan salin string ke dalamnya:
/* REMEMBER: always add one to your array sizes in C, for safety! */
char buffer[14];
strcpy(buffer, "foo\nbaz\nbar");
Sekarang yang harus Anda lakukan adalah mencari pola dua karakter yang mewakili baris baru. Anda tidak diizinkan mencari hanya garis miring terbalik. Karena C digunakan untuk pemisahan string yang cukup banyak, itu akan memberi Anda kesalahan jika Anda mencoba. Anda dapat melihat ini jika Anda mencoba menulis:
char pattern[2];
strcpy(pattern, "\");
(Catatan: Ada pengaturan di kompiler untuk jika Anda menulis program yang hanya mencari garis miring terbalik. Tapi itu sangat jarang; garis miring terbalik sangat jarang digunakan, itulah sebabnya mereka dipilih untuk tujuan ini. Kami tidak akan mengubahnya menyalakan.)
Jadi mari kita buat pola yang kita inginkan, seperti ini:
char pattern[3];
strcpy(pattern, "\n");
Saat kami ingin membandingkan dua string dengan panjang tertentu, kami menggunakan strncmp
. Ini membandingkan sejumlah karakter dari string yang berpotensi lebih besar, dan memberi tahu Anda apakah mereka cocok atau tidak. Jadi strncmp("\nA", "\nB", 2)
mengembalikan 1 (benar). Ini meskipun string tidak sepenuhnya sama dengan panjang tiga ... tetapi karena hanya dua karakter yang diperlukan.
Jadi mari kita melangkahi buffer kita, satu karakter pada satu waktu, mencari dua karakter yang cocok dengan pola kita. Setiap kali kita menemukan urutan dua karakter dari garis miring terbalik diikuti oleh n, kita akan menggunakan pemanggilan sistem yang sangat khusus (atau "syscall") putc
untuk mengeluarkan jenis karakter khusus: kode ASCII 10 , untuk mendapatkan baris fisik baru .
#include "stdio.h"
#include "string.h"
char buffer[14]; /* actual length 13 */
char pattern[3]; /* actual length 2 */
int i = 0;
int main(int argc, char* argv[]) {
strcpy(buffer, "foo\nbar\nbaz");
strcpy(pattern, "\n");
while (i < strlen(buffer)) {
if (1 == strncmp(buffer + i, pattern, 2)) {
/* We matched a backslash char followed by n */
/* Use syscall for output ASCII 10 */
putc(10, stdout);
/* bump index by 2 to skip both backslash and n */
i += 2;
} else {
/* This position didn't match the pattern for a newline */
/* Print character with printf */
printf("%c", buffer[i]);
/* bump index by 1 to go to next matchable position */
i += 1;
}
}
/* final newline and return 1 for success! */
putc(10, stdout);
return 1;
}
Output dari program ini adalah hasil yang diinginkan ... string split!
foo
baz
bar
\t
untuk \ trolling ...
Benar-benar salah dari atas ke bawah. Namun diisi dengan omong kosong yang terdengar masuk akal yang telah mengacak informasi seperti apa yang ada di buku teks atau Wikipedia. Logika program tampak transparan dalam konteks informasi yang keliru, tetapi sepenuhnya menyesatkan. Bahkan variabel global dan mengembalikan kode kesalahan, untuk ukuran yang baik ...
...
Tentu saja, hanya ada satu karakter dalam representasi string C dari urutan literal sumber dua karakter \n
. Tetapi membuat buffer lebih besar tidak berbahaya, asalkan strlen()
digunakan untuk mendapatkan panjang aktual untuk beroperasi.
...
Kami mencoba meyakinkan pembaca bahwa strncmp
ini adalah operasi boolean yang cocok dengan (1) atau tidak (0). Tetapi sebenarnya memiliki tiga nilai kembali (-1 cocok kurang, 0 untuk sama, 1 untuk cocok lebih besar) . "Pola" dua karakter kami yang dibandingkan bukan [ \
, n
], melainkan [ \n
, \0
] ... mengambil terminator nol implisit. Ketika urutan tersebut meluncur melalui string, maka tidak akan pernah lebih besar dari urutan dua karakter yang dibandingkan dengan ... paling-paling itu akan menjadi nol jika ada baris baru yang berhenti di string input.
...
Jadi yang dilakukan adalah loop melalui string dan mencetaknya satu karakter pada satu waktu. Cabang teratas tidak pernah berjalan. (Meskipun Anda bisa mendapatkannya jika string Anda memiliki \n
kode lebih rendah dari itu, katakan tab ... yang dapat digunakan untuk menghilangkan karakter secara misterius dari output :-P)