কেন ifstream.eof () কোনও ফাইলের শেষ লাইনটি পড়ার পরে সত্য ফেরায় না?


11

যখন কোনও শিক্ষানবিস যদি স্ট্রিমিং স্ট্রিমিং পড়া শুরু করেন, তখন তার প্রবৃত্তিটি সাধারণত এমন দেখায় এমন লুপ ব্যবহার করে ফাইলটি পড়তে হয়:

while (!ifstream.eof()
{
...
}

যাইহোক, আমি এই কোডটি ব্যবহার করার সময় আমি লক্ষ্য করেছি যে এটি ফাইলটির শেষ লাইনটি দু'বার না পড়া পর্যন্ত এটি থামেনি। সি ++ প্রোগ্রামাররা মনে রাখবেন যে এটি আসলে কীভাবে ফাইল পড়তে হবে তা নয়। পরিবর্তে, তারা সাধারণত সুপারিশ করে যে যার ফাইল পড়তে হবে তার পরিবর্তে এইভাবে একটি লুপ ব্যবহার করুন:

while (ifstream >> someVar)
{
...
}

কোডের প্রথম অংশটি কেন সর্বদা সঠিকভাবে কাজ করতে ব্যর্থ হয়?


আমি ভাবতাম এখানে একটি সদৃশ হবে তবে আমি এখানে একটি খুঁজে পাচ্ছি না। স্ট্যাকওভারফ্লোতে প্রচুর নকল রয়েছে।
ডেভিড হামেন

উত্তর:


4

while (!ifstream.eof())লুপ কারণ স্ট্রিম / সি এবং সি ++ ফাইল যখন আপনি ফাইলের শেষে পৌঁছেছেন, বরং ইঙ্গিত যদি আপনি পড়তে চেষ্টা করেছি ভবিষ্যদ্বাণী করা না, কাজ করে না অতীত ফাইলের শেষে।

যদি ফাইলের শেষ লাইনটি একটি নতুন লাইন ( \n) অক্ষর দিয়ে শেষ হয় , তবে বেশিরভাগ পঠিত ক্রিয়া পড়া বন্ধ হয়ে যাবে যখন তারা সেই চরিত্রটির মুখোমুখি হয়েছিল এবং তারা সনাক্ত করতে পারে না যে এটি ফাইলের শেষ অক্ষর হিসাবে ঘটে। পরবর্তী পড়ার ক্রিয়াতে, এটি এমনও হতে পারে যে আরও অক্ষর যুক্ত করা হয়েছে এবং পাঠগুলি সেগুলি বের করতে সফল হবে।

স্ট্রিম এক্সট্রাকশন অপারেটর ( while (ifstream >> someVar)) ব্যবহার করে লুপটি কাজ করে কারণ স্ট্রিম এক্সট্রাকশন অপারেটর থেকে ফলটি মিথ্যা হিসাবে মূল্যায়ন করে যদি এটি সঠিক ধরণের কোনও আইটেম বের করতে না পারে। কোনও অক্ষর পড়ার বাকী না থাকলে এটিও ঘটে।


4

যাইহোক, সি ++ প্রোগ্রামাররা লক্ষ্য করে যে সর্বদা যা ঘটে তা হ'ল cin.eof () শেষ লাইনে দু'বার পড়া না হওয়া পর্যন্ত "সত্য" প্রত্যাবর্তন করে না।

যা হচ্ছে তা নয়। eofbitকোন একটি বুলিয়ান রূপান্তর একটি ভূমিকা পালন করে ( stream::operator bool(অথবা operator void*পুরোনো C ++))। শুধুমাত্র badbitএবং failbitজড়িত।

ধরা যাক আপনি একটি ফাইল পড়ছেন যা শ্বেতস্পেসে পৃথক সংখ্যাসমৃদ্ধ একটি ফাইল রয়েছে। চারপাশে ভিত্তিক একটি লুপ cin.eof()অনিবার্যভাবে ভুল হবে বা ifপরীক্ষায় পূর্ণ হবে । আপনি ইওএফ অবধি পড়ছেন না। আপনি সংখ্যা পড়ছেন। সুতরাং আপনার কোডটি সেই যুক্তিটি প্রকাশ করুন:

while (stream >> some_var) {
    process_value(some_var);
}

এটি ফাইলের শেষ লাইনটি শেষ হবে 0 42\nবা ঠিক 0 42( ফাইলের শেষ লাইনের শেষে কোনও নতুন লাইন নয়) তা কাজ করবে। যদি ফাইলটি শেষ হয় 0 42\n, শেষ ভাল পঠনটি 42 টি মানটি পুনরুদ্ধার করবে এবং লাইন চিহ্নিতকারীটির চূড়ান্ত প্রান্তটি পড়বে। নোট করুন যে ইওএফ চিহ্নিতকারীটি এখনও পড়েনি। process_valueসঙ্গে ফাংশন বলা হয় 42। প্রবাহ নিষ্কাশন অপারেটর >> পাশে কল ফাইলের শেষে লেখা আছে, এবং কিছুই যেহেতু বের করা হয়েছে, উভয় eofbitএবং failbitসেট হবে।

মনে করুন অন্যদিকে, ফাইলটি শেষ হয় 0 42(শেষ লাইনের শেষে কোনও নিউলাইন নেই)। সর্বশেষ ভাল পঠন ইওএফ চিহ্নিতকারীতে 42 টি সমাপ্তি মানটি পুনরুদ্ধার করবে। সম্ভবত আপনি এটি প্রক্রিয়া করতে চান ৪২. এই কারণেই eofbitইনপুট স্ট্রিম বুলিয়ান রূপান্তর অপারেটরে কোনও ভূমিকা রাখে না। স্ট্রিম এক্সট্রাকশন অপারেটর >> এর পরবর্তী কলটিতে, অন্তর্নিহিত যন্ত্রপাতি দ্রুত দেখতে পাবে যে eofbitইতিমধ্যে সেট করা আছে। এটি দ্রুত সেটিংসে ফলাফল করে failbit

কোডের প্রথম অংশটি কেন সর্বদা সঠিকভাবে কাজ করতে ব্যর্থ হয়?

কারণ আপনি লুপের শর্ত হিসাবে ইওএফের জন্য যাচাই করা উচিত নয়। লুপের শর্তটি আপনাকে কী করতে চেষ্টা করছে তা প্রকাশ করা উচিত, যা (উদাহরণস্বরূপ), একটি স্ট্রিম থেকে সংখ্যা বের করা।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.