नोब प्रोग्रामर यहाँ...तो कृपया मेरे साथ रहें। मैं एक मौजूदा टेक्स्ट फ़ाइल को एक सरणी में पास करने का प्रयास कर रहा हूं, हालांकि एक बार मेरा मुख्य मेनू उस फ़ाइल में मौजूद जानकारी को लोड करता है, भले ही मैं कोई बदलाव न करूं। यह सिर्फ जानकारी नहीं रख रहा है। यह प्रोग्राम उपयोगकर्ता को या तो एक नई फ़ाइल बनाने या अद्यतन करने और/या किसी मौजूदा फ़ाइल को लोड करने की अनुमति देता है। इस मुद्दे को कैसे ठीक किया जाए इस पर कोई विचार? आप सभी को धन्यवाद!

char fileName[20] = "";

void loadEmployee()
{
    FILE* fPtr;
    char singleLine[150];

    if (strcmp(fileName, "") == 0)
    {
        printf("\nWhat's the name of the file? ");
        scanf_s("%s", fileName, 20);
    }

    fopen_s(&fPtr, fileName, "r");

    while (!feof(fPtr))
    {
        fgets(singleLine, 150, fPtr);
        puts(singleLine);
    }
    fclose(fPtr);
}

void saveEmployee()
{
    FILE* fPtr;

    if (strcmp(fileName, "") == 0)
    {
        printf("\nWhat's the name of the file? ");
        scanf_s("%s", fileName, 20);
    }

    fopen_s(&fPtr, fileName, "w");

        for (int i = 0; i < numEmps; i++)
        {
            fprintf(fPtr, "%s %f %f\n", emps[i].emps.name, 
                        emps[i].emps.rate, emps[i].emps.hours);
        }
        fclose(fPtr);
}


void loadMenu()
{
    int i = 0;

    printf("1. Load from a file  \n");
    printf("2. Keyboard \n");
    scanf_s("%d", &choice);

    switch (choice)
    {
    case 1: loadEmployee();
        break;

    default:
        break;
    }

        do
        {
            printf("\nMAIN MENU\n");
            printf("1.Add Employee\n");
            printf("2.Edit Employee\n");
            printf("3.Print Employee\n");
            printf("4.Print ALL employees\n");
            printf("5.Exit\n");
            scanf_s("%d", &choice);

            switch (choice)
            {
            case 1: NameInput();
                break;
            case 2: printf("Choose employee: \n");
                for (int i = 0; i < numEmps; i++)
               {
                printf("%d. %s \n", i + 1, 
                                    emps[i].emps.name);
               }
                scanf_s("%d", &choice);

                empUpdate(choice - 1);

                break;

            case 3: printf("Choose employee: \n\n");
                for (int i = 0; i < numEmps; i++)
                {
                printf("%d) %s \n", i + 1, 
                                    emps[i].emps.name);
                }

                scanf_s("%d", &choice);
                printf("%s \n", emps[choice - 
                                1].emps.name);
                printf("%.2f \n", emps[choice - 
                                1].emps.hours);
                printf("%.2f \n", emps[choice - 
                                1].emps.rate);

                break;

            case 4: PayOutput();
                break;

            case 5: printf("Quitting program!");
                saveEmployee();
                return;

            default: printf("Invalid choice try again \n\n");
                break;
            }
        } while (choice != 5);
}  

int main()
{
    struct information empsi[20];
    loadMenu();
}
0
chessnotcheckers 5 अगस्त 2019, 04:30

2 जवाब

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

जैसा कि @ ह्यूगो ने कहा, प्रोग्राम फ़ाइल को पढ़ता है लेकिन सामग्री को संग्रहीत नहीं करता है। इसका मतलब है कि emps खाली रहेगा। जब आप बाहर निकलते हैं तो आप फ़ाइल को उसकी सामग्री को हटाने के लिए लिखने के लिए खोलते हैं। ब्यूज़ emps खाली है, कुछ भी नहीं लिखा है।

आप जिस तरह से लिख रहे हैं, उसी तरह पढ़कर इसे हल किया जा सकता है। मैं ठीक से नहीं जानता कि emps कैसा दिखता है, लेकिन कुछ इस तरह।

for( numEmps = 1; fgets(singleLine, 150, fPtr); numEmps++ ) {
    // I'm assuming emps is preallocated.
    struct Employee emp = emps[numEmps-1];
    sscanf(singleLine, "%80s %f %f",
        emp.emps.name,
        &emp.emps.rate,
        &emp.emps.hours
    );
}

feof का उपयोग करने के बजाय सूचना मैं fgets का रिटर्न मान देख रहा हूं। जैसा कि एडवर्ड करक ने बताया , पंक्तियों को पढ़ते समय eof की जांच न करें।


कोड में अन्य मुद्दे ...

आप जाँच नहीं कर रहे हैं कि आपकी फ़ाइलें वास्तव में खुली हैं या नहीं।

    fopen_s(&fPtr, fileName, "r");
    if( !fPtr ) {
        perror(fileName);
        exit(1);
    }

कोड बहुत सारे वैश्विक चर का उपयोग करता है। इससे कोड को समझना मुश्किल हो जाता है क्योंकि कुछ भी किसी भी समय उन ग्लोबल्स को बदल सकता है। इसके बजाय, फ़ंक्शन तर्कों और वापसी मूल्यों का लाभ उठाएं। तब आप किसी फ़ंक्शन को केवल उसे देखकर पूरी तरह से समझ सकते हैं।

उदाहरण के लिए, loadEmployee को स्ट्रक्चर को पॉप्युलेट करने के लिए और फ़ाइल नाम को पढ़ने के लिए लेना चाहिए, फिर इसे वापस पढ़ना चाहिए। saveEmployee समान है।

int loadEmployee(struct Employee *emps, char *fileName) {
    ...
    return numEmps;
}

void saveEmployee(struct Employee *emps, char *fileName) {
    ...
}

न तो उपयोगकर्ता को फ़ाइल नाम के लिए पूछने का प्रभारी होना चाहिए। यह कॉल करने वाले द्वारा संभाला जाना चाहिए। कार्य एक काम करना चाहिए; यह उन्हें सरल और अधिक लचीला बनाता है।

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

char *getFileName() {
    static char fileName[80] = "";

    if (strcmp(fileName, "") == 0)
    {
        printf("\nWhat's the name of the file? ");
        scanf("%20s", fileName);
    }

    return fileName;
}

...
switch(choice) {
    case 1:
        numEmps = loadEmployee(emps, getFileName());
        break;
    ...
    case 5:
        printf("Quitting program!");
        saveEmployee(emps, getFileName());
        return;
}
...

ये आपकी समस्या का स्रोत नहीं हैं, लेकिन ये आपके कोड को संरचित करने में मदद करेंगे ताकि इसे समझना और डीबग करना आसान हो।

0
Schwern 5 अगस्त 2019, 05:20

आपका फ़ंक्शन loadEmployee केवल एक char [] को लिखता है जो फ़ंक्शन के लिए स्थानीय है (जिसका अर्थ है कि इसे अंत में छोड़ दिया गया है)।

जब प्रोग्राम से बाहर निकलता है, तो आप wसंस्कार मोड में अपनी फ़ाइल को फिर से खोलकर कर्मचारी को « सेव » करते हैं, जो इसे साफ़ करता है, और इसके बाद जो होता है वह शायद बहुत कुछ नहीं करता है, इसलिए फ़ाइल खाली रहती है।

अपने फ़ंक्शन के बाहर फ़ाइल से डेटा को वास्तव में वापस करने या संग्रहीत करने का प्रयास करें ताकि बाद में इसका पुन: उपयोग किया जा सके।

1
hugo 5 अगस्त 2019, 04:45