Saya memiliki file teks bernama test.txt
Saya ingin menulis program C yang dapat membaca file ini dan mencetak konten ke konsol (asumsikan file hanya berisi teks ASCII).
Saya tidak tahu bagaimana cara mendapatkan ukuran variabel string saya. Seperti ini:
char str[999];
FILE * file;
file = fopen( "test.txt" , "r");
if (file) {
while (fscanf(file, "%s", str)!=EOF)
printf("%s",str);
fclose(file);
}
Ukuran 999
tidak berfungsi karena string yang dikembalikan oleh fscanf
bisa lebih besar dari itu. Bagaimana saya bisa memecahkan masalah ini?
sumber
stdout
.c
int, dan C akan menjamin bahwaEOF
tidak sama dengan karakter yang valid.Ada banyak jawaban bagus di sini tentang membacanya dalam potongan, saya hanya akan menunjukkan kepada Anda sedikit trik yang membaca semua konten sekaligus ke buffer dan mencetaknya.
Saya tidak mengatakan itu lebih baik. Tidak, dan seperti Ricardo kadang-kadang bisa buruk, tapi menurut saya ini adalah solusi yang bagus untuk kasus-kasus sederhana.
Saya menaburkannya dengan komentar karena ada banyak hal yang terjadi.
#include <stdio.h> #include <stdlib.h> char* ReadFile(char *filename) { char *buffer = NULL; int string_size, read_size; FILE *handler = fopen(filename, "r"); if (handler) { // Seek the last byte of the file fseek(handler, 0, SEEK_END); // Offset from the first to the last byte, or in other words, filesize string_size = ftell(handler); // go back to the start of the file rewind(handler); // Allocate a string that can hold it all buffer = (char*) malloc(sizeof(char) * (string_size + 1) ); // Read it all in one operation read_size = fread(buffer, sizeof(char), string_size, handler); // fread doesn't set it so put a \0 in the last position // and buffer is now officially a string buffer[string_size] = '\0'; if (string_size != read_size) { // Something went wrong, throw away the memory and set // the buffer to NULL free(buffer); buffer = NULL; } // Always remember to close the file. fclose(handler); } return buffer; } int main() { char *string = ReadFile("yourfile.txt"); if (string) { puts(string); free(string); } return 0; }
Beri tahu saya jika itu berguna atau Anda dapat belajar sesuatu darinya :)
sumber
buffer[string_size] = '\0';
bukanstring_size+1
? Afaik string sebenarnya berubah dari0
kestring_size-1
dan\0
karakter karenanya harus distring_size
, kan?ftell
danfseek
menemukan ukuran file tidak aman: securecoding.cert.org/confluence/display/seccode/…fclose(handle)
calloc(2)
daripadamalloc(1)
melewatkan harus mengatur terminator null.Alih-alih langsung mencetak karakter ke konsol karena file teks mungkin sangat besar dan Anda mungkin memerlukan banyak memori.
#include <stdio.h> #include <stdlib.h> int main() { FILE *f; char c; f=fopen("test.txt","rt"); while((c=fgetc(f))!=EOF){ printf("%c",c); } fclose(f); return 0; }
sumber
Gunakan "read ()" sebagai ganti o fscanf:
ssize_t read(int fildes, void *buf, size_t nbyte);
Berikut ini contohnya:
http://cmagical.blogspot.com/2010/01/c-programming-on-unix-implementing-cat.html
Bagian yang dikerjakan dari contoh itu:
f=open(argv[1],O_RDONLY); while ((n=read(f,l,80)) > 0) write(1,l,n);
Pendekatan alternatif adalah dengan menggunakan
getc
/putc
membaca / menulis 1 karakter sekaligus. Jauh kurang efisien. Contoh yang bagus: http://www.eskimo.com/~scs/cclass/notes/sx13.htmlsumber
read
akan memungkinkan Anda membaca dalam sejumlah karakter. Baca secukupnya untuk mengisi buffer Anda, lalu buang buffer Anda ke layar, kosongkan, dan ulangi hingga Anda mencapai akhir file.Dua pendekatan melompat ke pikiran.
Pertama, jangan gunakan
scanf
. Gunakanfgets()
yang mengambil parameter untuk menentukan ukuran buffer, dan yang membiarkan karakter baris baru tetap utuh. Sebuah loop sederhana di atas file yang mencetak konten buffer secara alami harus menyalin file secara utuh.Kedua, gunakan
fread()
atau idiom C umum denganfgetc()
. Ini akan memproses file dalam potongan berukuran tetap atau satu karakter dalam satu waktu.Jika Anda harus memproses file melalui string yang dipisahkan spasi putih, gunakan salah satu
fgets
ataufread
untuk membaca file, dan sesuatu sepertistrtok
membagi buffer di spasi kosong. Jangan lupa untuk menangani transisi dari satu buffer ke buffer berikutnya, karena string target Anda kemungkinan besar menjangkau batas buffer.Jika ada persyaratan eksternal yang dapat digunakan
scanf
untuk melakukan pembacaan, maka batasi panjang string yang mungkin terbaca dengan bidang presisi dalam penentu format. Dalam kasus Anda dengan buffer 999 byte, lalu katakanscanf("%998s", str);
mana yang akan menulis paling banyak 998 karakter ke buffer yang menyisakan ruang untuk terminator nul. Jika satu string lebih panjang dari buffer Anda yang diperbolehkan, maka Anda harus memprosesnya menjadi dua bagian. Jika tidak, Anda memiliki kesempatan untuk memberi tahu pengguna tentang kesalahan dengan sopan tanpa membuat lubang keamanan buffer overflow.Terlepas dari itu, selalu validasi nilai yang dikembalikan dan pikirkan tentang cara menangani masukan yang buruk, berbahaya, atau hanya salah format.
sumber
Anda dapat menggunakan
fgets
dan membatasi ukuran string baca.char *fgets(char *str, int num, FILE *stream);
Anda dapat mengubah
while
kode Anda menjadi:while (fgets(str, 100, file)) /* printf("%s", str) */;
sumber
Anda dapat membaca seluruh file dengan alokasi memori dinamis, tetapi bukan ide yang baik karena jika file terlalu besar, Anda dapat mengalami masalah memori.
Jadi lebih baik membaca bagian pendek dari file dan mencetaknya.
#include <stdio.h> #define BLOCK 1000 int main() { FILE *f=fopen("teste.txt","r"); int size; char buffer[BLOCK]; // ... while((size=fread(buffer,BLOCK,sizeof(char),f)>0) fwrite(buffer,size,sizeof(char),stdout); fclose(f); // ... return 0; }
sumber