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

संपादित करें: मैंने पुराना कोड हटा दिया है क्योंकि मैंने seg गलती को ठीक कर दिया है। अब मैंने कमांड लाइन पर फीड किए जाने वाले डेटा को बदल दिया है। लेकिन ऐसा लगता है कि या तो फाइलें नहीं खुल रही हैं या यह लाइनों की सही गिनती नहीं कर रही है क्योंकि जब मैं इसे चलाता हूं तो प्रोग्राम हमेशा 0 लाइनें लौटाएगा।

यहाँ अद्यतन कोड है:

#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>

const char *get_filename_ext(const char *filename) {
    const char *dot = strrchr(filename, '.');
    if(!dot || dot == filename) return "";
    return dot + 1;
}

int printdir(char *dir, char *targetFileExt, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;
      int spaces = depth*4;
    int totalLines=0;

    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return -1;
    }
    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        lstat(entry->d_name,&statbuf);
        if(S_ISDIR(statbuf.st_mode)) {
            /* Found a directory, but ignore . and .. */
            if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0){
                continue;
            }
            printf("%*s%s/\n",spaces,"",entry->d_name);
            /* Recurse at a new indent level */
            totalLines = printdir(entry->d_name, targetFileExt, depth+1);
        }
        else {
          printf("%*s%s\n",spaces,"",entry->d_name);

          char *currentFileExt = get_filename_ext(entry->d_name);

          if(*currentFileExt == *targetFileExt){
            //open the file for reading
            FILE *fPtr = fopen(entry->d_name, "r");

            //traverse the file
            while(!feof(fPtr)){
              //if there is a new line character
              int temp = fgetc(fPtr);
              if(temp=='\n'){
                //add a line to the total amount of lines
                totalLines++;
              }
            }

            //close the file
            fclose(fPtr);
            fPtr=NULL;
          }
        }
    }
    chdir("..");
    closedir(dp);

    return totalLines;
}

int main(int argc, char* argv[])
{
    char *topdir, pwd[2]=".";
    char *ext;
    if (argc < 2 || argc > 3)
        topdir=pwd;
    else if(argc == 2){
      topdir=argv[1];
    }
    else if(argc == 3){
      topdir=argv[1];
      ext=argv[2];
    }

    printf("Directory scan of %s\n",topdir);
    int lines = printdir(topdir, ext, 0);
    printf("You have written %d lines of %s code!\n", lines, ext);

    return 0;
}
2
joycem8845 24 पद 2020, 04:40

1 उत्तर

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

सबसे पहले, फ़ाइल नाम एक्सटेंशन की जांच करें: if(*currentFileExt == *targetFileExt) केवल एक वर्ण वाले फ़ाइल एक्सटेंशन के लिए काम करेगा। ".com" के लिए खोज करने पर विचार करें, और आप एक ".c" फ़ाइल का सामना करते हैं। get_filename_ext() डॉट के बाद पहले अक्षर के लिए एक पॉइंटर लौटाएगा। तब आप 'c' == 'c' की तुलना कर रहे होंगे। इसके बजाय strcmp() का उपयोग करने पर विचार करें, और सुनिश्चित करें कि targetFileExt में प्रमुख बिंदु नहीं है, क्योंकि आपका कोड इस प्रकार सेट किया गया है।

दूसरा, printdir() अपने वर्तमान स्वरूप में उपनिर्देशिकाओं से लाइन काउंट जमा नहीं करता है। परिदृश्य पर विचार करें:

  • हम .c फ़ाइलें खोज रहे हैं।
  • आप जिस निर्देशिका में खोज रहे हैं, उसमें दो उपनिर्देशिकाएँ हैं, A और B, और कुछ नहीं।
  • A में 10 LOC .c फ़ाइल है, और B में 20 LOC .c फ़ाइल है।

जब आप कोड चलाते हैं:

  1. आप printdir() को main() से कॉल करते हैं, मान लें कि आपका कोड पहले A से मिलता है
  2. फ़ंक्शन स्वयं को पुनरावर्ती रूप से कॉल करता है और 10 देता है, इसलिए totalLines को 10 का मान दिया जाता है।
  3. अगले लूप पुनरावृत्ति पर फ़ंक्शन का सामना B से होता है।
  4. फ़ंक्शन स्वयं को पुनरावर्ती रूप से कॉल करता है, 20 देता है, इसलिए totalLines को 20 का मान दिया जाता है।
  5. आपने पहले लूप पुनरावृत्ति से 10 लाइनें खो दी हैं।

इसे ठीक करने के लिए, आपके पास तीन विकल्प हैं:

  • फंक्शन सिग्नेचर को इसमें बदलें: int printdir(char *dir, char *targetFileExt, int depth, int totalLines); और int totalLines=0; को हटा दें। फ़ंक्शन में इसे इस तरह कॉल करें: totalLines = printdir(entry->d_name, targetFileExt, depth+1, totalLines); इसे main() से कॉल करें जो कुललाइन के लिए 0 पास कर रहा है।

  • एक लाइन काउंट वेरिएबल के लिए पॉइंटर को स्वीकार करने के लिए फ़ंक्शन सिग्नेचर में बदलें, और जब आप लाइनों का सामना करते हैं तो इसे बढ़ाएँ। (निहितार्थ। गृहकार्य के रूप में छोड़ दिया गया)

  • वैश्विक लाइन गणना चर का प्रयोग करें। (निहितार्थ। गृहकार्य के रूप में छोड़ दिया गया)

1
vmt 24 पद 2020, 09:50