मैं यह सुनिश्चित करने के लिए fread() का उपयोग करने का प्रयास कर रहा हूं कि कोई फ़ाइल एक jpeg है या नहीं, मेरा विचार यह सुनिश्चित करने के लिए कि यह एक jpeg है, फ़ाइल के शीर्षलेख को पढ़ने के लिए fread() का उपयोग करना था, और फिर, यदि यह है - फाइल को कॉपी करें। मैं समझता हूं कि मानक जेपीईजी हेडर 0xff 0xd8 0xff 0xe(0 to f) है, इसलिए मैंने एक फ़ाइल के पहले चार बाइट्स को पढ़ने के लिए एक प्रोग्राम बनाया।

#include <stdio.h>
#include <stdint.h>

typedef uint8_t BYTE;

int main (int argc, char *argv[])
{
    FILE *in = fopen(argv[1], "rb");
    
    FILE *out = fopen("output.jpg", "wb");
    
    BYTE buffer [4096];
    
    while (fread(buffer, 1, sizeof(buffer), in))
    {
        if ((buffer[0] == 0xff) & (buffer[1] == 0xd8) & (buffer[2] == 0xff) & ((buffer[3] & 0xf0) == 0xe0))
        {
            fwrite(buffer, 1, sizeof(buffer), out);
        }
    }
    
    fclose(in);
    fclose(out);
}

हालांकि, प्रोग्राम चलाने के बाद, जब मैं output.jpg को खोलने का प्रयास करता हूं, तो मुझे संदेश मिलता है: Invalid or Unsupported Image Format

मैंने यह जांचने का फैसला किया कि मैं पैराग्राफ को बदलकर fwrite() सही ढंग से उपयोग कर रहा था:

while (fread(buffer, 1, sizeof(buffer), in))
        {
            fwrite(buffer, 1, sizeof(buffer), out);
        }

और इस मामले में, output.jpg करता है सही ढंग से खुलता है, जिससे मुझे लगता है कि यह मेरी कोशिश है कि मैं fread() का उपयोग उस फ़ाइल प्रकार की जांच करने के लिए करूं जिससे समस्या हुई है। क्या मुझे किसी भिन्न फ़ंक्शन का उपयोग करना चाहिए, या क्या मैं कुछ गलत तरीके से स्वरूपित कर रहा हूं?

-2
BlueKhakis 14 फरवरी 2021, 07:21
2
& && होना चाहिए। पूर्व "बिटवाइज़ और" है जबकि बाद वाला "तार्किक और" है।
 – 
kaylum
14 फरवरी 2021, 07:24
इससे भी महत्वपूर्ण बात यह है कि if कंडीशन चेक केवल एक बार किया जाना चाहिए, हर लूप के लिए नहीं। क्योंकि परिभाषा के अनुसार हेडर केवल फ़ाइल की शुरुआत में होता है और डेटा का हर हिस्सा पढ़ा नहीं जाता है।
 – 
kaylum
14 फरवरी 2021, 07:26
साथ ही, fread के रिटर्न वैल्यू की जांच करें और वास्तव में पढ़े गए से अधिक बाइट्स कभी न लिखें।
 – 
dxiv
14 फरवरी 2021, 07:27
हाय @kaylum, बिटवाइज़ और लॉजिकल "ands" में क्या अंतर है?
 – 
BlueKhakis
14 फरवरी 2021, 07:37

1 उत्तर

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

यहां दो समस्याएं हैं।

आपका प्रोग्राम लूप में फ़ाइल से एक बार में 4KB तक पढ़ रहा है, और आप फ़ाइल पर लिखने से पहले यह देखने के लिए प्रत्येक 4KB ब्लॉक के पहले 4 बाइट्स की जाँच कर रहे हैं कि क्या यह jpeg हेडर है। आप इसे केवल एक बार फ़ाइल के आरंभिक पठन पर करना चाहते हैं। यदि यह चेक पास हो जाता है तो लूप में पढ़ते और लिखते रहें, अन्यथा ब्रेक आउट हो जाता है।

दूसरी समस्या यह है कि आप फ़ाइल में हमेशा sizeof(buffer) बाइट लिख रहे हैं। fread फ़ंक्शन उससे कम बाइट्स पढ़ रहा होगा, और यदि ऐसा है तो आप अतिरिक्त डेटा लिखेंगे जो आपको नहीं करना चाहिए। कितना पढ़ा गया, यह जानने के लिए आपको fread के रिटर्न वैल्यू को कैप्चर करना होगा और फिर उसे fwrite में लिखने की लंबाई के रूप में उपयोग करना होगा।

5
dbush 14 फरवरी 2021, 07:27