Stream Errors in C++: अभी तक हमने Input व Output के लिए cout व cin Objects को बडी आसानी से Use किया है और हम ये मान रहे हैं, कि जिस तरह से “C” Language में Input व Output के लिए गलत Control Strings का प्रयोग करने से Errors आती हैं, उस तरह की Errors “C++” में नहीं आती हैं। लेकिन ये बात हमेंशा सही नहीं होती है।
मानलो कि Program में एक Integer संख्या 10 Input करनी है और User String Format में “Ten” Input कर दे] तो क्या होगा। या फिर मानलो कि User बिना किसी मान को Input किए हुए ही Enter Key Press कर दे। इसी तरह से यदि कोई Hardware Fail हो जाए। इन विभिन्न प्रकार की स्थितियों में इन cin व cout Objects इस प्रकार की Errors को Handle नहीं कर पाते हैं।
चलिए, हम ऐसी कुछ स्थितियों को समझने की कोशिश करते हैं। यहां हम जिन Techniques को देख रहे हैं, उन में से ज्यादातर को File I/O के लिए भी समान प्रकार से उपयोग में ले सकते हैं।
Error-Status Bits
Stream Error-Status Bits ios Class में Define किया गया एक enum Member है, जिसे Input या Output Operations के समय होने वाली Errors को Report करने के लिए बनाया गया है।
विभिन्न प्रकार के ios Functions को इन Error Bits को Read व Set करने के लिए Use किया जा सकता है। इनमें से कुछ को निम्न Table में दर्शाया गया है:
Inputting Numbers
चलिए, देखते हैं कि जब हम Numbers Input करते हैं, उस समय विभिन्न प्रकार की Errors को किस प्रकार से Handle किया जा सकता है। ये तरीका Keyboard व Disk File दोनों से Numbers को Read करते समय Apply किया जा सकता है। Concept ये है कि goodbit को Check किया जाए। यदि ये True नहीं होता है, तो ये Indicate करता है, कि Input में कोई Error है साथ ही User को फिर से Correct Input प्रदान करने के लिए एक और Chance देता है।
while(1)
{
cout << “\nEnter an integer: “;
cin >> i;
if(cin.good()){
cin.ignore(10, ‘\n’); // Remove newline
break; // Exit loop
}
cin.clear(); // Clear the error bits
cout << “Incorrect input “;
cin.ignore(10, ‘\n’) // Remove newline
}
cout << “integer is “ << i; // Error-free integer
ये तरीका सबसे ज्यादा Errors उस स्थिति में Find करता है जब User Digits Input करने के बजाय Non-Digits Input कर देता है। ये प्रक्रिया failbit को Set कर देती है। साथ ही ये Bit System-Related Failures को भी Detect करता है, जो कि Disk File के साथ ज्यादा Generate होती हैं। Floating-Point Numbers जैसे कि Long double, double या float के साथ भी इसी प्रक्रिया को Use करके Errors को Detect किया जा सकता है।
Too Many Characters
Input Streams से Characters को Read करते समय भी कुछ Errors Generate हो सकती हैं। मुख्यतया जो Extra Characters Input Buffer में पडे रह जाते हैं, वे ज्यादा परेशानी पैदा करते हैं। क्योंकि ये Characters अगले Input Object को Assign हो जाते हैं।
सामान्यतया एक New Line Character Input Buffer में रह जाता है, जबकि कई बार कुछ अन्य Characters Input Buffer में रह जाते हैं। इन Extra Characters की परेशानी से बचने के लिए हम istream Class के ignore(MAX, DELIM) Member Function का प्रयोग कर सकते हैं।
ये Input Stream से Specify किए गए Limit तक के Character व Delimiter Character को Input Stream से Read करता है और उन्हें Input Buffer से Flush कर देता है। हमारे Example में निम्न Line यही काम कर रही है:
cin.ignore(10, ‘\n’);
ये Statement Input Buffer को 10 Characters Read करने के लिए कहता है, जिसमें ‘\n’ Character भी शामिल है, और उन्हें Remove कर देता है।
No-Input Input
Blank-Space, Enters व ‘\n’ Characters सामान्यतया तब Ignore हो जाते हैं, जब हम Numbers Input करते हैं। इसके कुछ अवांछित Side Effects हो जाते हैं। उदाहरण के लिए User को Number Enter करने के लिए Prompt किया जाए और User बिना कोई Number Enter किए हुए ही Enter Key Press कर दे। User के ऐसा करने पर Cursor अगली Line पर चला जाता है, जबकि Stream किसी Number के Input होने का इन्तजार करती रहती है।
यदि User फिर से Enter Key Press करे, तो Cursor एक और Line नीचे आ जाता है और इसी तरह से आगे भी हो सकता है। अत% एक Professional Program में ये सुविधा होनी चाहिए कि वह Whitespaces को Ignore ना करे। ये काम हम skipws Flag का प्रयोग करके कर सकते हैं:
cout << "\nEnter an integer: ";
cin.unsetf(ios::skipws); // don't ignore Whitespace
cin >> i;
if( cin.good() )
{
// no error
}
// error
अब यदि User बिना किसी Digit को Enter किए Enter Key या Space Key को Press करता है, तो failbit Set हो जाता है और एक Error Generate होता है। अत% Program User से बता सकता है कि उसे क्या करना है और Cursor Screen पर अगली Line पर Scroll नहीं होता है।
Inputting Strings and Characters
User जब Characters व Strings Input करता है, तब किसी प्रकार की कोई Mistake नहीं हो सकती है। क्योंकि Computer में Input के समय सभी Numbers व Characters String की तरह ही Interpret होते हैं। फिर भी यदि Characters व Strings किसी Disk File से आ रहे हों, तो हमें ये Check करना जरूरी हो जाता है, कि कहीं File से EOF Indication या कोई अन्य Special Character तो Read नहीं हो रहा है।
Error-Free Distances
चलिए, हम English Distance Class में इस Concept को Apply करते हैं। इस Program में यदि User गलत Input करता है, तो Program एक Error Message देता है और सही Input करने के लिए फिर से Prompt करता है। ये Program बहुत ही Simple है जिसमें एक Member Function getdist() को Expand करके Error को Handle करने की सुविधा प्राप्त की गई है।
इस Program में कुछ और Statements को भी Add किया गया है जो ये निश्चित कर देते हैं कि User Feet में Floating Point Values Input ना करे। ऐसा करना इसलिए जरूरी है, क्योंकि Feet एक Integer मान है और Inches एक Floating Point मान है और User आसानी से Confuse हो सकता है।
सामान्यतया यदि Program एक Integer मान चाहता है, और हम उसे Floating Point मान प्रदान कर देते हैं, तो Extraction Operator बिना किसी प्रकार का Error दि, Terminate हो जाता है। हमारा Program इस प्रकार की Error के बारे में जानना चाहता है, इसलिए वह Feet की Values को Integer के रूप में Read नहीं करता है, बल्कि String की तरह Read करता है। फिर Program उस String को अपने एक Library Function isint() द्वारा Examine करता है, जो कि उस स्थिति में True Return करता है, जब String ये Prove कर देता है, कि वह एक Integer मान है।
इस int Test को Pass करने के लिए जरूरी होता है कि String में केवल Integers ही Stored हों और वे Numbers –32768 से 32767 तक की Range में हों। यदि String int Test को Pass कर लेता है तो Program इस String को एक Library Function atoi() का प्रयोग करके एक Actual Integer में Convert कर देता है।
Program में Inches का मान एक Integer मान है। Program इसकी Range को Check करता है, जो कि “0 से अधिक व 12 से कम” तक हो सकती है। Program इसको ios के Error Bit के लिए भी Check करता है। सामान्यतया Fail Bit तब Set हो जाती है, जब User Integer के स्थान पर कोई Non – Digit Key Type कर देता है।
// EnglErr.cpp
// Input checking with English Distance class
#include <iostream.h>
#include <string.h> // for strchr()
#include <stdlib.h> // for atoi()
int isint(char*); // prototype
const int IGN = 10; // characters to ignore
class Distance // English Distance class
{
private:
int feet;
float inches;
public:
Distance() // constructor (no args)
{ feet = 0; inches = 0.0; }
Distance(int ft, float in) // constructor (two args)
{ feet = ft; inches = in; }
void showdist() // display distance
{ cout << feet << "\'-" << inches << '\"'; }
void getdist(); // get length from user
};
void Distance::getdist() // get length from user
{
char instr[80]; // for input string
while(1) // cycle until feet are right
{
cout << "\n\nEnter feet: ";
cin.unsetf(ios::skipws); // do not skip white space
cin >> instr; // get feet as a string
if( isint(instr) ) // is it an integer?
{ // yes
cin.ignore(IGN, '\n'); // eat chars, including newline
feet = atoi(instr); // convert to integer
break; // break out of 'while'
} // no, not an integer
cin.ignore(IGN, '\n'); // eat chars, including newline
cout << "Feet must be an integer\n"; // start again
} // end while feet
while(1) // cycle until inches are right
{
cout << "Enter inches: ";
cin.unsetf(ios::skipws); // do not skip white space
cin >> inches; // get inches (type float)
if(inches>=12.0 || inches<0.0)
{
cout << "Inches must be between 0.0 and 11.99\n";
cin.clear(ios::failbit);// "artificially" set fail bit
}
if( cin.good() ) // check for cin failure
{ // (most commonly a non-digit)
cin.ignore(IGN, '\n'); // eat the newline
break; // input is OK, exit 'while'
}
cin.clear(); // error; clear the error state
cin.ignore(IGN, '\n'); // eat chars, including newline
cout << "Incorrect inches input\n"; // start again
} // end while inches
}
int isint(char* str) // return true if the string
{ // represents type int
int slen = strlen(str); // get length
if( slen==0 || slen > 5) // if no input, or too long
return 0; // not an int
for(int j=0; j<slen; j++) // check each character
// if not digit or minus
if( (str[j] < '0' || str[j] > '9') && str[j] != '-' )
return 0; // string is not an int
long n = atol(str); // convert to long int
if( n< -32768L || n>32767L ) // is it out of int range?
return 0; // if so, not an int
return 1; // it is an int
}
void main()
{
Distance d; // make a Distance object
char ans;
do
{
d.getdist(); // get its value from user
cout << "\nDistance = ";
d.showdist(); // display it
cout << "\nDo another (y/n)? ";
cin >> ans;
cin.ignore(IGN, '\n'); // eat chars, including Newline
} while(ans != 'n'); // cycle until 'n'
}
हमने इस Program में एक और Trick Use की है जहां Error-State Flag को Manually Set किया है। हमने ऐसा इसलिए किया है, क्योंकि हम ये तय करना चाहते हैं कि Inches का मान 0 से अधिक है और 12.0 से कम है। यदि ऐसा नहीं है तो हम failbit को निम्न Statement द्वारा Set कर देते हैं:
cin.clear(ios::failbit); // set failbit
जब Program cin.good() Statement द्वारा Errors को Check करता है, तब उसे failbit Set मिलता है, जो कि इसके लिए इस बात का Signal होता है, कि User ने सही Input नहीं किया है और Input Incorrect है।
All-Character Input
Error Handling का एक और तरीका ये है कि हम Input किए जाने वाले सभी Characters को Read करें, चाहे वह Number हो चाहे String हो। फिर हमारा Code String को Character By Character प्राप्त करके ये Check कर लेता है कि User ने सही Input प्रदान किया है या नही।
यदि सही Input प्रदान ना किया हो तो String को Appropriate Number में Convert कर दिया जाता है। इस Approach की Detail इस बात पर निर्भर करती है कि हम अपने Program द्वारा किस प्रकार का Input प्राप्त करना चाहते हैं। इसलिए हम यहां पर किसी प्रकार का कोई उदाहरण नहीं दे रहे हैं। हालांकि हम चाहे जिस प्रकार से Error की Handling कर रहे हों, हमें Error Status Bits द्वारा Error को Check करना चाहिए।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook C++ Programming Language in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
C++ Programming Language in Hindi | Page: 666 | Format: PDF