मैं इन दोनों को बयानों को छोटे तरीके से तैयार करना चाहता था:

//FUNCTION PROTOTYPES
int checkCommandLineArguments(int argc, char *argv[]);
int checkFile(char *argv[]);

//MAIN FUNCTIONxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
int main(int argc, char *argv[])
{
    checkCommandLineArguments(argc, &argv[1]);
    checkFile(&argv[1]);
    return 0;
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



//F1–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
int checkCommandLineArguments(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        exit(1);
    }
    return 0;
}
//–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

//F2–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
int checkFile(char *argv[])
{
    FILE *file = fopen(argv[1], "r");
    if (NULL == file)
    {
        printf("Cannot open file!\n");
        exit(1);
    }
    return 0;
}
//–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

मैंने एक टर्नरी ऑपरेटर का उपयोग करने के बारे में सोचा:

(argc != 2) ? printf("Error X\n"), exit(1) : (NULL == file) ? printf("Cannot open file!\n"),
        exit(1): return 0 ;

हालांकि, यह काम नहीं कर रहा है (शायद वापसी/निकास बयानों के कारण)। मैं इसे कैसे ठीक कर सकता हूं, या ऐसा करने के कोई अन्य (अधिक उपयुक्त) तरीके हैं?

शुक्रिया!

1 संपादित करें यह टिप्पणी की गई है कि टर्नरी ऑपरेटर बयानों के साथ काम नहीं करते हैं, इसलिए वह विकल्प तालिका से बाहर है। हालांकि, मैं अभी भी ऐसा करने के बेहतर तरीकों की तलाश में हूं।

2 संपादित करें मैंने एक और विस्तारित कोड उदाहरण जोड़ा, क्योंकि इसे टिप्पणियों में पूछा गया है।

0
NilsK 30 अक्टूबर 2020, 20:00

2 जवाब

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

टर्नरी ऑपरेटर में एक्जिट/रिटर्न स्टेटमेंट का उपयोग कैसे करें?

तुम नहीं कर सकते। एक टर्नरी ऑपरेटर का दूसरा और तीसरा ऑपरेंड एक्सप्रेशन होना चाहिए, और एक return कथन एक एक्सप्रेशन नहीं है (देखें टर्नरी ऑपरेटर और सी में वापसी)। हालांकि, दोनों के लिए दोनों के लिए शून्य अभिव्यक्ति की अनुमति है, जैसे exit(1), जिस स्थिति में ऑपरेशन का परिणाम भी एक शून्य अभिव्यक्ति है।

इसके अतिरिक्त, आपके विशिष्ट कोड के संबंध में, अल्पविराम ऑपरेटर (,) की सभी सी ऑपरेटरों की सबसे कम प्राथमिकता है। इसलिए, यदि आप किसी अन्य ऑपरेशन में कॉमा एक्सप्रेशन को ऑपरेंड के रूप में उपयोग करने का इरादा रखते हैं, तो आपको इसे कोष्ठक में बदलना होगा।

मैं इन दोनों को बयानों को छोटे तरीके से तैयार करना चाहता था:

क्यों? केवल संक्षिप्तता या संक्षिप्तता एक उपयोगी उद्देश्य नहीं है। यदि यह आपके कोड को मानव के लिए पढ़ने और समझने में कठिन बनाता है, तो आपके कोड को छोटा करना एक दायित्व है।

लेकिन अगर आपका मतलब है कि आप एक ही बात को अधिक बस, अधिक स्पष्ट रूप से, और / या कम अनावश्यक रूप से व्यक्त करना चाहते हैं, तो यह आपको आगे ले जा सकता है उन रूपों की ओर जो छोटे भी होते हैं। उदाहरण के लिए, आप किसी फ़ंक्शन या मैक्रो में तर्क को इनकैप्सुलेट कर सकते हैं। व्यक्तिगत रूप से मैं अक्सर एक मैक्रो की आपूर्ति करता हूं जो ऐसा कुछ दिखता है:

#define ERROR_IF_NZ(cond, message) do { \
    if (cond) { \
        fputs(message, stderr); \
        exit(1); \
    } \
} while (0)

इसका उपयोग करके, आपका कोड इस तरह दिख सकता है:

ERROR_IF_NZ(argc != 2, "Error X\n");
ERROR_IF_NZ(NULL == file, "Cannot open file!\n");

मैक्रो नाम को समायोजित करें ताकि यह आपको सबसे अधिक समझ में आए, और देखें! यह न केवल मूल कोड से स्पष्ट है, बल्कि छोटा भी है, भले ही आप मैक्रो परिभाषा की लंबाई की गणना करें।

अद्यतन

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

2
John Bollinger 30 अक्टूबर 2020, 22:09

आपके द्वारा संपादन के साथ जोड़ा गया कोड पठनीय है और कमोबेश ठीक है, आपको इसे टर्नरी ऑपरेटर ट्रिक्स से भ्रमित करने की आवश्यकता नहीं है।

केवल checkFile बहुत व्यर्थ है, आप फ़ाइल खोलते हैं और फिर आप फ़ाइल के साथ कुछ भी किए बिना फ़ंक्शन को छोड़ देते हैं और अंततः फ़ाइल हैंडल को लीक कर देते हैं।

आप शायद यह पैटर्न चाहते हैं:

int main(int argc, char *argv[])
{
    checkCommandLineArguments(argc, &argv[1]);
    FILE *file = checkFile(&argv[1]);

    // do stuff with file

    fclose(file);
    return 0;
}

FILE *checkFile(char *argv[])
{
    FILE *file = fopen(argv[1], "r");
    if (NULL == file)
    {
        printf("Cannot open file!\n");
        exit(1);
    }
    return file;
}
2
Jabberwocky 30 अक्टूबर 2020, 20:38