मेरा कार्यक्रम वर्णों को एक सरणी में पढ़ना और इसे कंसोल पर प्रदर्शित करना है। लेकिन मुझे नहीं पता कि यह केवल पहले 3 अक्षर क्यों पढ़ता है।

#include <iostream>

using namespace std;
int main() {    
    int length=0,i;
    char str[10];
    cout<<"Enter a string"<<"\n";

    for(i=0; str[i] != '\0'; i++) {
        cin>>str[i];
    }

    for(int i=0; str[i]!='\0'; i++) {
        cout<<str[i];
        length++;
    }
    cout<<"\n"<<"Length of the string="<<""<<length<<"\n";
}

आउटपुट जैसा दिखता है:

enter image description here

0
Dr.pK 14 जिंदा 2018, 21:33

5 जवाब

सबसे बढ़िया उत्तर

टीएल; डीआर संस्करण

std::string str; //use std::string. practically no reasons not to in C++
if (cin >> str) // read into string and test that read succeeded.
{
    std::cout << str << '\n'
              << "Length of the string=" << str.length() << endl;
}

आस्कर के संस्करण को समझाना और उबारना

for(i=0; str[i] != '\0'; i++){ // str[i] tested here
    cin>>str[i]; // but it has no assigned value until here.

एक मान निर्दिष्ट करने से पहले str[i] का उपयोग करता है। प्रोग्राम को संभवतः str के लिए आवंटित मेमोरी के ब्लॉक में एक शून्य वर्ण मिला और समय से पहले बंद हो गया, लेकिन तकनीकी रूप से कुछ भी हो सकता है यदि आप एक अप्रारंभीकृत चर का उपयोग करते हैं। उदाहरण के लिए, आपको अशक्त खोजने से पहले 3 बार अपेक्षित परिणाम मिला। कार्यक्रम कभी भी शून्य नहीं पाया गया और हमेशा के लिए चला गया। गेंडाओं की बारिश हो सकती थी। कुछ भी।

int i = 0;
do {
    cin>>str[i];
} while (str[i++] != '\0');

पढ़ता है फिर परीक्षण करता है। लेकिन एक स्ट्रीम में डेटा की लाइनें सी-स्टाइल स्ट्रिंग्स नहीं हैं और शून्य के साथ समाप्त नहीं होती हैं।

int i = 0;
do {
    cin>>str[i];
} while (!std::isspace(str[i++]));

जब व्हॉट्सएप पाया जाता है, तो बाहर निकल जाता है, आमतौर पर अशक्त के बजाय किसी शब्द के अंत का संकेत देता है।

लेकिन क्या होगा अगर cin>>str[i]; किसी कारण से विफल हो गया?

int i = 0;
do {
    cin>>str[i];
} while (cin && !std::isspace(str[i++]));

यह सुनिश्चित करने के लिए एक परीक्षण जोड़ता है कि कुछ पढ़ा गया था। लेकिन क्या होगा यदि 10 से अधिक वर्ण हों और char str[10]; अतिप्रवाह हो?

int i = 0;
do {
    cin>>str[i];
} while (cin && !std::isspace(str[i]) && ++i < sizeof(str));

जब तक मैं पढ़ रहा हूं यह तब तक कानूनी है जब तक कि मैं [expr.cond] और [expr.log.and] गलत नहीं पढ़ रहा हूं, जब ++i होता है, तब तक अनुक्रमिक रूप से !std::isspace(str[i]) && ++i < sizeof(str)) में !std::isspace(str[i]) को प्रभावित नहीं करने की गारंटी है

लेकिन क्या होगा यदि आप शून्य खोजने से पहले अंतरिक्ष से बाहर निकलते हैं? str समाप्त नहीं हुआ है और एक स्ट्रिंग नहीं है! यह बाद में कार्यक्रम में लूप के लिए बर्बाद कर देता है।

int i = 0;
do {
    cin>>str[i];
} while (cin && !std::isspace(str[i]) && ++i < sizeof(str));
if (i == sizeof(str))
{
    str[sizeof(str)-1] = '\0';
}

मुझे लगता है कि इसमें वह सब कुछ शामिल है जो आप यहां चलाने की संभावना रखते हैं।

3
user4581301 16 जिंदा 2018, 01:05

यहां कुछ समस्याएं हैं जिन पर मैंने गौर किया:

  1. आप इसे आरंभ करने से पहले str की सामग्री की जांच कर रहे हैं।
  2. आप मान रहे हैं कि आप जिस स्ट्रिंग को स्ट्रीम से ला रहे हैं वह शून्य-समाप्त हो जाएगी, लेकिन वास्तव में ऐसा नहीं है।
  3. आप जाँच नहीं कर रहे हैं कि सिन सही ढंग से काम कर रहा है या नहीं
  4. आप यह सुनिश्चित करने के लिए जांच नहीं करते हैं कि स्ट्रिंग 10 वर्ण या उससे कम है, इससे आप बफर के अंत से पहले ओवरफ्लो कर सकते हैं
  5. जब आप सरणी की लंबाई की जाँच कर रहे हैं, तो फिर से आप मान लेते हैं कि स्ट्रिंग अशक्त-समाप्त है

यदि आप इन मुद्दों को ठीक करना चाहते हैं और अभी भी चार बफर का उपयोग करना चाहते हैं, तो उपयोगकर्ता 4581301 का व्यापक उत्तर देखें। हालांकि, मैं केवल std::string. पर स्विच करने का सुझाव दूंगा उदाहरण के लिए:

#include<iostream>

using namespace std;

int main()
{
    string str;
    cout<<"Enter a string"<<"\n";
    if (cin >> str) {
        cout << str << endl;
        cout << "Length of the string = " << str.length() << endl;
    }
}
4
Alex 14 जिंदा 2018, 22:27

आप चरित्र दर चरित्र पढ़ते हैं और इसे str[i]; लेकिन फिर आप str[i]!='\0' की जांच करने से पहले i++ बढ़ा देते हैं।

इस दृष्टिकोण के साथ दो मुद्दे हैं: सबसे पहले, आप उस स्थिति पर एक मान की जांच करते हैं जो उस समय नहीं लिखा गया है। दूसरा, cin>>str[i] कभी भी स्ट्रिंग टर्मिनेशन कैरेक्टर नहीं लिखेगा - यह केवल मान्य वर्णों में पढ़ता है, और यदि इनपुट समाप्त हो जाता है (जैसे EOF द्वारा), कुछ भी नहीं लिखा जाता है।

तो आप इसे गलत तरीके से देख रहे हैं।

यदि आप एक नई पंक्ति तक अधिकतम 10 वर्ण पढ़ना चाहते हैं (अर्थात जब उपयोगकर्ता एंटर दबाता है), तो fgets का उपयोग करें। या - और यह पसंदीदा विकल्प है - cin का उपयोग करें और एक std::string-ऑब्जेक्ट में लिखें।

int main()
{
    std::string str;
    cin >> str;
    std::cout << str << std::endl;
}
2
Stephan Lechner 14 जिंदा 2018, 21:45

Str[i] != '\0' str[i] पर संग्रहीत पूर्व-मौजूदा डेटा की जांच करता है, न कि उपयोगकर्ता-इनपुट मान की।

1
RFlaum 14 जिंदा 2018, 21:37

स्ट्रिंग इनिशियलाइज़ेशन जोड़ें:

char str[10] = {'\0'};

और इसके साथ रीडिंग बदलें:

char c;
for(int i = 0; cin>> c && c!=/*add your termination cond. here*/ && i < 10;++i)
    str[i] = c;

तो आप यह सुनिश्चित कर सकते हैं कि स्ट्रिंग सही मानों से भरी हुई है और उचित रूप से समाप्त हो गई है।

लेकिन बेहतर समाधान std::string का उपयोग करना होगा। उस स्थिति में आपको आकारों की जांच करने की आवश्यकता नहीं है, क्योंकि स्ट्रिंग अपने आप बढ़ती है। उदाहरण के लिए:

    std::string str;
    for(char c; cin>>c && c!=/*add your termination cond. here*/;) 
        str += c;
0
StPiere 14 जिंदा 2018, 21:52