C में '\ 0' और printf ()


21

C के एक परिचयात्मक पाठ्यक्रम में, मैंने सीखा है कि संचय करते समय तारों को \0इसके अंत में अशक्त वर्ण के साथ संग्रहीत किया जाता है। लेकिन अगर मैं एक स्ट्रिंग प्रिंट करना चाहता था, तो कहो printf("hello")कि मैंने पाया है कि यह खत्म नहीं होता है\0 निम्नलिखित कथन के

printf("%d", printf("hello"));

Output: 5

लेकिन यह असंगत प्रतीत होता है, जहां तक ​​मुझे पता है कि तार की तरह चर मुख्य मेमोरी में संग्रहीत होते हैं और मुझे लगता है कि कुछ छपाई करते समय इसे मुख्य मेमोरी में भी संग्रहीत किया जा सकता है, फिर अंतर क्यों?


1
इस तथ्य के अलावा कि आपका कोड कम से कम छूट गया है );, आप उस कोड के साथ क्या दिखाने का इरादा रखते हैं? आपने यह कैसे साबित किया है कि यह एक के साथ समाप्त नहीं होता है \0?
ग्लोगल

और इसमें जो मेमोरी स्टोर की जाती है, उसका इससे क्या लेना-देना है?
त्सुकिरोग्लू फोटी

सी में सभी शाब्दिक तार वास्तव में पात्रों की सरणियों, जो कर रहे हैं शामिल हैं अशक्त-टर्मिनेटर।
कुछ प्रोग्रामर

@glglgl मुझे लगता है कि प्रिंटफ़ () स्क्रीन पर प्रिंट करने वाले वर्ण की संख्या लौटाता है।
अजय मिश्र

4
@AjayMishra हाँ, और इसे वास्तव में 5 वर्णों को मुद्रित करना चाहिए था। समाप्ति 0 बाइट स्क्रीन पर मुद्रित नहीं है।
glglgl

जवाबों:


13

नल बाइट एक स्ट्रिंग के अंत को चिह्नित करता है। यह स्ट्रिंग की लंबाई में नहीं गिना जाता है और जब स्ट्रिंग के साथ मुद्रित किया जाता है तो वह मुद्रित नहीं होता हैprintf । मूल रूप से, अशक्त बाइट फ़ंक्शंस को बताता है कि स्टॉप हेरफेर कब करना है।

यदि आप एक अंतर देखेंगे यदि आप charएक स्ट्रिंग के साथ आरंभीकृत सरणी बनाते हैं । sizeofऑपरेटर का उपयोग करना रिक्त बाइट सहित सरणी के आकार को प्रतिबिंबित करेगा। उदाहरण के लिए:

char str[] = "hello";
printf("len=%zu\n", strlen(str));     // prints 5
printf("size=%zu\n", sizeof(str));    // prints 6

मुझे लगा कि कहानी अलग होगी printf()। TBH मुझे नहीं पता कि कैसे printf()काम करता है।
अजय मिश्र 13

8

printfमुद्रित वर्णों की संख्या लौटाता है। '\0'मुद्रित नहीं किया जाता है - यह सिर्फ संकेत देता है कि इस तार में और अधिक वर्ण नहीं हैं। यह स्ट्रिंग की लंबाई की ओर भी गिना नहीं जाता है

int main()
{
    char string[] = "hello";

    printf("szieof(string) = %zu, strlen(string) = %zu\n", sizeof(string), strlen(string));
}

https://godbolt.org/z/wYn33e

sizeof(string) = 6, strlen(string) = 5

6

आपकी धारणा गलत है। आपका तार वास्तव में एक के साथ समाप्त होता है\0

यह 5 अक्षरों के होते हैं h, e, l, l,o और 0 चरित्र।

"इनर" print()कॉल आउटपुट क्या वर्णों की संख्या है जो प्रिंट किए गए थे, और यह 5 है।


6

सी में सभी शाब्दिक तार वास्तव में वर्णों के एरे हैं, जिसमें नल-टर्मिनेटर शामिल हैं।

हालांकि, शून्य टर्मिनेटर को एक स्ट्रिंग (शाब्दिक या नहीं) की लंबाई में नहीं गिना जाता है, और इसे मुद्रित नहीं किया जाता है। नल टर्मिनेटर मिलने पर छपाई रुक जाती है।


वहाँ किसी भी तरह यह एक सरणी में स्ट्रिंग भंडारण के बिना सत्यापित करने के लिए है?
अजय मिश्र 13

1
@ अजय मिश्रा वैसे तो तार पहले से ही एक सरणी में है (जैसा कि उल्लेख किया गया है) ... लेकिन अगर कोई अशक्त टर्मिनेटर नहीं था, तो printfस्ट्रिंग की सीमा से बाहर चला जाएगा, और "यादृच्छिक" या "कचरा" अक्षर प्रिंट करेंगे, और वापस आ जाएंगे स्ट्रिंग की लंबाई से अलग संख्या। यदि आप पहले से ही स्ट्रिंग की लंबाई जानते हैं, तो आप यह भी देख सकते हैं कि क्या उस इंडेक्स पर वर्ण है '\0', जो काम करेगा, लेकिन तकनीकी रूप से अपरिभाषित व्यवहार है यदि एरे के आकार में टर्मिनेटर (जैसे कि char arr[5] = "hello";, जिसमें जोड़ नहीं होगा) सरणी के लिए टर्मिनेटर)।
कुछ प्रोग्रामर ने

@AjayMishra Yes E. g।, आप कर सकते हैं char * p = "Hello"; int i = 0; while (p[i] != '\0') { printf("%d: %c", i, p[i]); i++; }और देख सकते हैं कि यह कैसे चलता है: यह तर्जनी और उस रेखा पर सामग्री के साथ लाइनें दिखाता है। इंडेक्स 4 के बाद, यह 0 वर्ण पाता है और लूप को तोड़ता है। वहां आप देखते हैं कि 0 वर्ण है।
ग्लोगल

6

सभी उत्तर वास्तव में अच्छे हैं लेकिन मैं इन सभी को पूरा करने के लिए एक और उदाहरण जोड़ना चाहूंगा

#include <stdio.h>

int main()
{
    char a_char_array[12] = "Hello world";

    printf("%s", a_char_array);
    printf("\n");

    a_char_array[4] = 0; //0 is ASCII for null terminator

    printf("%s", a_char_array);
    printf("\n");

    return 0;
}

उन लोगों के लिए ऑनलाइन gdb पर यह कोशिश नहीं करना चाहता, आउटपुट है:

नमस्ते दुनिया

नरक

https://linux.die.net/man/3/printf

क्या यह समझने में सहायक है कि एस्केप टर्मिनेटर क्या करता है? यह एक चार सरणी या एक स्ट्रिंग के लिए एक सीमा नहीं है। यह चरित्र है जो उस आदमी को कहेगा जो यहाँ तक पार्स करता है, (प्रिंट) पार्स।

पुनश्च: और यदि आप पार्स करते हैं और इसे चार सरणी के रूप में प्रिंट करते हैं

for(i=0; i<12; i++)
{
    printf("%c", a_char_array[i]);
}
printf("\n");

आपको मिला:

हेलो दुनिया

हालांकि, डबल एल के बाद व्हॉट्सएप, शून्य टर्मिनेटर है, हालांकि, एक चार सरणी को पार्स करना, बस हर बाइट का चार मूल्य होगा। यदि आप एक और पार्स करते हैं और प्रत्येक बाइट ("% d%, char_array [i]) का अंतर मान प्रिंट करते हैं, तो आप देखेंगे कि (आपको ASCII कोड- int प्रतिनिधित्व मिलता है) व्हाट्सएप का मान 0 है।


4

में Cसमारोह printf()मुद्रित चरित्र की संख्या देता है, \0एक है nullटर्मिनेटर जो सी भाषा में स्ट्रिंग के अंत का संकेत करने के लिए किया जाता है और वहाँ कोई में बनाया गया है stringके रूप में प्रकार c++, हालांकि एक कम से कम अधिक होना करने के लिए अपने सरणी आकार की जरूरत की संख्या की तुलना में charआप चाहते हैं स्टोर करने के लिए।

यहाँ रेफरी है: cpp ref printf ()


3

लेकिन क्या होगा अगर मैं एक स्ट्रिंग प्रिंट करना चाहता हूं, तो प्रिंटफ ("हैलो") कहो, हालांकि मैंने पाया है कि यह किसी भी स्टेटमेंट के साथ 0 से समाप्त नहीं होता है

printf("%d", printf("hello"));

Output: 5

तुम गलत हो। यह कथन इस बात की पुष्टि नहीं करता है कि स्ट्रिंग शब्द शाब्दिक "hello"शून्य चरित्र को समाप्त नहीं करता है '\0'। इस कथन ने पुष्टि की कि समारोहprintf स्ट्रिंग के तत्वों को तब तक आउटपुट करता है जब तक कि शून्य चरित्र का सामना नहीं किया जाता है।

जब आप ऊपर दिए गए कथन के अनुसार एक स्ट्रिंग शाब्दिक का उपयोग कर रहे होते हैं, तब संकलक स्थिर भंडारण अवधि के साथ एक चरित्र सरणी बनाता है जिसमें स्ट्रिंग शाब्दिक के तत्व होते हैं।

तो वास्तव में यह अभिव्यक्ति

printf("hello")

संकलक द्वारा संसाधित किया जाता है जैसे कि कुछ

static char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
printf( string_literal_hello );

इसमें फंक्शन प्रिंटफ की Th क्रिया आप निम्नलिखित तरीके की कल्पना कर सकते हैं

int printf( const char *string_literal )
{
    int result = 0;

    for ( ; *string_literal != '\0'; ++string_literal )
    {    
        putchar( *string_literal );
        ++result;
    }

    return result;
}

स्ट्रिंग शाब्दिक "हैलो" में संग्रहीत वर्णों की संख्या प्राप्त करने के लिए आप निम्नलिखित कार्यक्रम चला सकते हैं

#include <stdio.h>

int main(void) 
{
    char literal[] = "hello";

    printf( "The size of the literal \"%s\" is %zu\n", literal, sizeof( literal ) );

    return 0;
}

कार्यक्रम का आउटपुट है

The size of the literal "hello" is 6

0

आपको पहले अपनी अवधारणा को साफ़ करना होगा .. जैसा कि जब आप सरणी से निपटते हैं, तो इसे साफ़ कर दिया जाएगा, प्रिंट कमांड आप इसका उपयोग केवल वर्णों को गिनने के लिए कर रहे हैं, जो कि पैरेन्थेसिस के भीतर रखे गए हैं। सरणी स्ट्रिंग में इसकी आवश्यक है कि यह \ 0 के साथ समाप्त हो जाएगा


0

एक स्ट्रिंग वर्णों का एक वेक्टर है। इसमें उन पात्रों का क्रम शामिल है जो स्ट्रिंग बनाते हैं, इसके बाद विशेष समाप्ति वर्ण स्ट्रिंग: '\ 0'

उदाहरण: char str [10] = {'H', 'e', ​​'l', 'l', 'o', '\ 0'};

उदाहरण: निम्न वर्ण वेक्टर एक स्ट्रिंग नहीं है क्योंकि यह '0' के साथ समाप्त नहीं होता है

char str [2] = {'h', 'e'};


सी में कोई वैक्टर नहीं हैं, मुझे लगता है।
अजय मिश्रा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.