Pertama, buat ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
Dua metode standar adalah:
Asumsikan bahwa setiap baris terdiri dari dua angka dan bacalah token dengan token:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
Penguraian berbasis garis, menggunakan aliran string:
#include <sstream>
#include <string>
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int a, b;
if (!(iss >> a >> b)) { break; } // error
// process pair (a,b)
}
Anda tidak boleh mencampur (1) dan (2), karena parsing berbasis token tidak melahap baris baru, jadi Anda mungkin berakhir dengan baris kosong palsu jika Anda menggunakan getline()
setelah ekstraksi berbasis token membuat Anda sampai akhir baris sudah.
int a, b; char c; while ((infile >> a >> c >> b) && (c == ','))
while(getline(f, line)) { }
konstruk dan mengenai penanganan kesalahan, silakan lihat artikel (saya) ini: gehrcke.de/2011/06/… (saya pikir saya tidak perlu memiliki hati nurani yang buruk memposting ini di sini, bahkan sedikit sebelum tanggal jawaban ini).Gunakan
ifstream
untuk membaca data dari file:Jika Anda benar-benar perlu membaca baris demi baris, maka lakukan ini:
Tetapi Anda mungkin hanya perlu mengekstrak pasangan koordinat:
Memperbarui:
Dalam kode Anda yang Anda gunakan
ofstream myfile;
, namuno
dalamofstream
singkatanoutput
. Jika Anda ingin membaca dari file (input) gunakanifstream
. Jika Anda ingin membaca dan menulis digunakanfstream
.sumber
getline
ada distring
lihat , jadi jangan lupa#include <string>
Membaca file baris demi baris dalam C ++ dapat dilakukan dengan beberapa cara berbeda.
[Cepat] Loop dengan std :: getline ()
Pendekatan paling sederhana adalah dengan membuka panggilan std :: ifstream dan loop menggunakan std :: getline (). Kode ini bersih dan mudah dimengerti.
[Cepat] Gunakan Boost's file_description_source
Kemungkinan lain adalah dengan menggunakan pustaka Boost, tetapi kode mendapat sedikit lebih banyak verbose. Kinerja sangat mirip dengan kode di atas (Loop with std :: getline ()).
[Tercepat] Gunakan kode C
Jika kinerja sangat penting untuk perangkat lunak Anda, Anda dapat mempertimbangkan menggunakan bahasa C. Kode ini bisa 4-5 kali lebih cepat daripada versi C ++ di atas, lihat patokan di bawah ini
Benchmark - Mana yang lebih cepat?
Saya telah melakukan beberapa tolok ukur kinerja dengan kode di atas dan hasilnya menarik. Saya telah menguji kode dengan file ASCII yang berisi 100.000 baris, 1.000.000 baris dan 10.000.000 baris teks. Setiap baris teks rata-rata berisi 10 kata. Program ini dikompilasi dengan
-O3
optimasi dan outputnya diteruskan/dev/null
untuk menghapus variabel waktu logging dari pengukuran. Terakhir, namun tidak kalah pentingnya, setiap potongan kode mencatat setiap baris denganprintf()
fungsi untuk konsistensi.Hasilnya menunjukkan waktu (dalam ms) yang diambil oleh setiap bagian kode untuk membaca file.
Perbedaan kinerja antara kedua pendekatan C ++ minimal dan seharusnya tidak membuat perbedaan dalam praktik. Performa kode C adalah apa yang membuat benchmark itu mengesankan dan bisa menjadi pengubah permainan dalam hal kecepatan.
sumber
std::cout
vsprintf
.printf()
fungsi dalam semua kasus untuk konsistensi. Saya juga telah mencoba menggunakanstd::cout
dalam semua kasus dan ini sama sekali tidak membuat perbedaan. Seperti yang baru saja saya jelaskan dalam teks, output dari program berjalan/dev/null
sehingga waktu untuk mencetak garis tidak diukur.cstdio
. Anda harus mencoba dengan pengaturanstd::ios_base::sync_with_stdio(false)
. Saya kira Anda akan memperoleh kinerja jauh lebih baik (Ini tidak dijamin karena implementasi-didefinisikan ketika sinkronisasi dimatikan).Karena koordinat Anda dimiliki bersama sebagai pasangan, mengapa tidak menulis struct untuknya?
Kemudian Anda dapat menulis operator ekstraksi yang kelebihan beban untuk istreams:
Dan kemudian Anda dapat membaca file koordinat langsung ke vektor seperti ini:
sumber
int
token dari aliranoperator>>
? Bagaimana cara membuatnya bekerja dengan parser backtracking (yaitu ketikaoperator>>
gagal, memutar kembali aliran ke posisi sebelumnya dan kembali palsu atau sesuatu seperti itu)?int
token, makais
aliran akan mengevaluasifalse
dan loop pembacaan akan berakhir pada titik itu. Anda dapat mendeteksi ini di dalamoperator>>
dengan memeriksa nilai balik dari masing-masing bacaan. Jika Anda ingin memutar kembali aliran, Anda akan meneleponis.clear()
.operator>>
dalamnya lebih tepat untuk mengatakanis >> std::ws >> coordinates.x >> std::ws >> coordinates.y >> std::ws;
karena jika tidak Anda mengasumsikan bahwa aliran input Anda dalam mode skipping-spasi.Memperluas jawaban yang diterima, jika inputnya adalah:
Anda masih dapat menerapkan logika yang sama, seperti ini:
sumber
Meskipun tidak perlu menutup file secara manual, tetapi ada baiknya untuk melakukannya jika ruang lingkup variabel file lebih besar:
sumber
Jawaban ini untuk visual studio 2017 dan jika Anda ingin membaca dari file teks yang lokasinya relatif terhadap aplikasi konsol yang dikompilasi.
pertama-tama masukkan filefile Anda (test.txt dalam kasus ini) ke dalam folder solusi Anda. Setelah kompilasi, simpan file teks dalam folder yang sama dengan applicationName.exe
C: \ Users \ "username" \ source \ repos \ "solutionName" \ "solutionName"
sumber
Ini adalah solusi umum untuk memuat data ke dalam program C ++, dan menggunakan fungsi readline. Ini dapat dimodifikasi untuk file CSV, tetapi pembatasnya adalah ruang di sini.
sumber