Dalam C , manipulator iomanip tertentu mempamerkan tingkah laku yang dikenali sebagai 'melekit', di mana mereka terus mempengaruhi aliran sehingga ditetapkan semula secara eksplisit. Tingkah laku ini boleh membawa kepada hasil yang tidak dijangka, seperti yang dilihat dalam coretan kod berikut:
std::stringstream ss; ss.fill('0'); ss.setf(ios::right, ios::adjustfield); ss << setw(2) << timestruct.tm_mday; ss << timestruct.tm_hour; ss << timestruct.tm_min; std::string filingTime = ss.str(); // BAD: '0794'
Dalam contoh ini, kami menjangkakan manipulator setw() memformat medan tm_mday dengan lebar 2 dan right-justify keluarannya. Walau bagaimanapun, tm_hour dan tm_min dicetak tanpa sebarang pemformatan. Ini kerana setw() bukan manipulator 'melekit', bermakna ia hanya mempengaruhi operasi sisipan seterusnya.
Berdasarkan perbincangan dalam ulasan, perkara berikut manipulator dikelaskan sebagai 'melekit':
Manipulator ini semuanya mengembalikan objek dan bukannya aliran, menunjukkan bahawa mereka melakukan operasi hanya pada objek seterusnya yang akan dimasukkan ke dalam strim.
Ini manipulator melakukan operasi pada strim itu sendiri, tanpa menjejaskan keadaannya untuk operasi berikutnya.
Terutamanya, setw() ialah satu-satunya manipulator yang kelihatan berkelakuan berbeza pada sistem pengarang. Walaupun ia bukan manipulator 'melekit', ia boleh dibuat untuk berkelakuan seperti menggunakan objek format tersuai, seperti yang ditunjukkan dalam kod berikut:
#include <iostream> #include <iomanip> struct SquareBracktAroundNextItem { SquareBracktAroundNextItem(std::ostream& str) : m_str(str) {} std::ostream& m_str; }; struct PutSquareBracket {}; SquareBracktAroundNextItem operator<<(std::ostream& str, PutSquareBracket const& data) { return SquareBracktAroundNextItem(str); } template<typename T> std::ostream& operator<<(SquareBracktAroundNextItem const& bracket, T const& data) { std::ios_base::fmtflags flags = bracket.m_str.flags(); std::streamsize currentPrecision = bracket.m_str.precision(); bracket.m_str << '[' << std::fixed << std::setprecision(10) << data << std::setprecision(currentPrecision) << ']'; bracket.m_str.flags(flags); return bracket.m_str; } int main() { std::cout << 5.34 << "\n" // Before << PutSquareBracket() << 5.34 << "\n" // Temp change settings. << 5.34 << "\n"; // After }
Output:
5.34 [5.3400000000] 5.34
Ringkasnya, kebanyakan manipulator iomanip dalam C adalah 'melekit,' bermakna ia terus menjejaskan strim sehingga ditetapkan semula secara eksplisit. setw() ialah pengecualian yang ketara, tetapi ia boleh dibuat 'melekit' menggunakan objek format tersuai.
Atas ialah kandungan terperinci Mengapa Beberapa C Iomanipulator Mempamerkan Tingkah Laku 'Lekit'?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!