Pertanyaan Bagaimana cara menyalin file teks ke string di C?


Saya perlu menyalin isi file teks ke array karakter yang dialokasikan secara dinamis.

Masalah saya adalah ukuran isi file; Google mengungkapkan bahwa saya perlu digunakan fseek dan ftell, tetapi untuk itu file tersebut tampaknya perlu dibuka dalam mode biner, dan itu hanya memberikan sampah.

EDIT: Saya mencoba membuka dalam mode teks, tetapi saya mendapatkan angka aneh. Berikut kode (saya telah menghilangkan kesalahan sederhana untuk memeriksa kejelasan):

long f_size;
char* code;
size_t code_s, result;
FILE* fp = fopen(argv[0], "r");
fseek(fp, 0, SEEK_END);
f_size = ftell(fp); /* This returns 29696, but file is 85 bytes */
fseek(fp, 0, SEEK_SET);
code_s = sizeof(char) * f_size;
code = malloc(code_s);
result = fread(code, 1, f_size, fp); /* This returns 1045, it should be the same as f_size */

4
2017-08-16 19:13


asal


Jawaban:


Akar masalahnya ada di sini:

FILE* fp = fopen(argv[0], "r");

argv [0] adalah program yang dapat dijalankan, BUKAN parameternya. Itu pasti tidak akan menjadi file teks. Coba argv [1], dan lihat apa yang terjadi kemudian.


14
2017-08-16 19:55



Anda tidak dapat menentukan ukuran file dalam karakter tanpa membaca data, kecuali Anda menggunakan enkode lebar tetap.

Sebagai contoh, sebuah file dalam UTF-8 yang panjangnya 8 byte bisa menjadi apa saja dari 2 hingga 8 karakter.

Itu bukan batasan dari file API, itu adalah pembatasan alami tidak ada pemetaan langsung dari "ukuran data biner" menjadi "jumlah karakter."

Jika Anda memiliki enkode fixed-width maka Anda dapat membagi ukuran file dalam byte dengan jumlah byte per karakter. ASCII adalah contoh paling jelas dari ini, tetapi jika file Anda dikodekan dalam UTF-16 dan Anda kebetulan berada di sistem yang memperlakukan poin kode UTF-16 sebagai tipe karakter internal "asli" (yang meliputi Java, .NET dan Windows) maka Anda dapat memprediksi jumlah "karakter" untuk mengalokasikan seolah-olah UTF-16 adalah lebar tetap. (UTF-16 adalah lebar variabel karena karakter Unicode di atas U + FFFF dikodekan dalam beberapa poin kode, tetapi banyak pengembang waktu mengabaikan ini.)


5
2017-08-16 19:19



Saya cukup yakin argv [0] tidak akan menjadi file teks.


2
2017-08-16 19:47



Berikan ini coba (belum dikompilasi ini, tapi saya sudah melakukan ini bazillion kali, jadi saya cukup yakin itu setidaknya dekat):

char* readFile(char* filename)
{
    FILE* file = fopen(filename,"r");
    if(file == NULL)
    {
        return NULL;
    }

    fseek(file, 0, SEEK_END);
    long int size = ftell(file);
    rewind(file);

    char* content = calloc(size + 1, 1);

    fread(content,1,size,file);

    return content;
}

2
2017-08-16 19:59



Jika Anda mengembangkan Linux (atau sistem operasi mirip Unix lainnya), Anda dapat mengambil ukuran file dengan stat sebelum membuka file:

#include <stdio.h>
#include <sys/stat.h>

int main() {
   struct stat file_stat;

   if(stat("main.c", &file_stat) != 0) {
      perror("could not stat");
      return (1);
   }
   printf("%d\n", (int) file_stat.st_size);

   return (0);
}

EDIT: Ketika saya melihat kode, saya harus masuk ke baris dengan poster lain:

Array yang mengambil argumen dari panggilan-program dibangun dengan cara ini:

[0] nama program itu sendiri
[1] argumen pertama diberikan
[2] argumen kedua diberikan
[n] argumen ke-n diberikan

Anda juga harus memeriksa argc sebelum mencoba menggunakan field selain '0' dari argv-array:

if (argc < 2) {
   printf ("Usage: %s arg1", argv[0]);
   return (1);
}

2
2017-08-16 19:22



Kamu dapat memakai fseek untuk file teks juga.

  • fseek hingga akhir file
  • ftell offset
  • fseek kembali ke awal

dan Anda memiliki ukuran file


1
2017-08-16 19:17



argv [0] adalah path ke executable dan dengan demikian argv [1] akan menjadi input pengguna pertama yang dikirimkan. Cobalah untuk mengubah dan menambahkan beberapa pengecekan kesalahan sederhana, seperti memeriksa apakah fp == 0 dan kami mungkin keliru untuk membantu Anda lebih jauh.


1
2017-08-16 19:54



Anda dapat membuka file, meletakkan kursor di akhir file, menyimpan offset, dan kembali ke bagian atas file, dan membuat perbedaan.


0
2017-08-16 19:16