Открыть каталог с помощью C

Я принимаю путь через ввод командной строки.

Когда я делаю

dir=opendir(args[1]);

он не входит в цикл ... т.е. _2 _...

Как передать ввод командной строки в указатель dir?

void main(int c,char **args)
{
    DIR *dir;
    struct dirent *dent;
    char buffer[50];
    strcpy(buffer, args[1]);
    dir = opendir(buffer);   //this part
    if(dir!=NULL)
    {
        while((dent=readdir(dir))!=NULL)
            printf(dent->d_name);
    }
    close(dir);
}

./a.out  /root/TEST is used to run the program..
./a.out --> to execute the program
/root/TEST --> input by the user i.e valid path

person Vinod K    schedule 24.08.2010    source источник
comment
Пожалуйста, предоставьте соответствующую часть вашего кода. Ваш вопрос непонятен, по крайней мере, для меня. opendir возвращает DIR *. Он возвращает NULL в двух случаях: невозможно получить доступ к каталогу или не удалось выделить память для хранения результата.   -  person jweyrich    schedule 24.08.2010
comment
@Vinod K: Как вы выполняете этот код / ​​какую командную строку вы используете для его запуска?   -  person Thanatos    schedule 24.08.2010
comment
@Vinod: распечатайте args [1] и вручную проверьте, существует ли он. 1) Он существует? 2) Умещается ли ваш путь в 50 байтов (вы должны использовать strncpy)? 3) Что будет, если не передать параметр? Добавьте туда надлежащие условия.   -  person jweyrich    schedule 24.08.2010
comment
@rasjani, как мне принять ответ ??? .. я не знаю об этом ... я новичок в этом ..   -  person Vinod K    schedule 24.08.2010
comment
@Vinod K - вернитесь к своим старым вопросам. Найдите ответ, который лучше всего отвечает на вопрос (если он есть), и щелкните значок галочки с серым контуром (он должен стать зеленым).   -  person detly    schedule 24.08.2010
comment
Я собираюсь рискнуть и предположить, что /root/TEST либо не является каталогом, либо у вас нет прав для поиска в нем. Попробуйте запустить свой код, используя /tmp или . в качестве каталога.   -  person paxdiablo    schedule 24.08.2010
comment
@Vinod K: нажмите обведенную галочку слева от ответа, который вы хотите принять. Он находится прямо под кнопками «проголосовать за» / «проголосовать против».   -  person Thanatos    schedule 24.08.2010
comment
вместо dir = open (buffer), когда я делаю dir = open (/ root / TEST) ... он работает нормально.   -  person Vinod K    schedule 24.08.2010
comment
@Vinod, я предполагаю, что в предыдущем комментарии вы имели в виду opendir, а не open. Что выводит ls -ald /root /root/TEST?   -  person paxdiablo    schedule 24.08.2010
comment
ребята ... он работает ... спасибо много   -  person Vinod K    schedule 24.08.2010
comment
Ладно, проблема была ... в чем именно?   -  person paxdiablo    schedule 24.08.2010
comment
последнее ... что означают эти [.] и [..] ..   -  person Vinod K    schedule 24.08.2010
comment
@Vinod, это текущий и родительский каталог. Например, если вы находитесь в /dir1/dir2, тогда cd . оставит вас там, а cd .. перенесет вас в /dir1. (и имейте в виду, что если вы хотите поговорить с кем-то конкретным, используйте текст «@paxdiablo» где-нибудь в своем комментарии - таким образом пользователь получит уведомление).   -  person paxdiablo    schedule 24.08.2010
comment
спасибо .. проблема .. я не знаю ... он не работал раньше ... теперь он работает ... спасибо agn ..   -  person Vinod K    schedule 24.08.2010
comment
Ах, да, печально известный Heisenbug :-)   -  person paxdiablo    schedule 24.08.2010


Ответы (4)


Вам действительно стоит опубликовать свой код (a), но начнем. Начните с чего-нибудь вроде:

    #include <stdio.h>
    #include <dirent.h>

    int main (int argc, char *argv[]) {
        struct dirent *pDirent;
        DIR *pDir;

        // Ensure correct argument count.

        if (argc != 2) {
            printf ("Usage: testprog <dirname>\n");
            return 1;
        }

        // Ensure we can open directory.

        pDir = opendir (argv[1]);
        if (pDir == NULL) {
            printf ("Cannot open directory '%s'\n", argv[1]);
            return 1;
        }

        // Process each entry.

        while ((pDirent = readdir(pDir)) != NULL) {
            printf ("[%s]\n", pDirent->d_name);
        }

        // Close directory and exit.

        closedir (pDir);
        return 0;
    }

В вашем случае вам нужно проверить, что args[1] установлен и относится к фактическому каталогу. Пример запуска, где tmp - это подкаталог вне моего текущего каталога, но вы можете использовать любой допустимый каталог, дает мне: testprog tmp

[.]
[..]
[file1.txt]
[file1_file1.txt]
[file2.avi]
[file2_file2.avi]
[file3.b.txt]
[file3_file3.b.txt]

Также обратите внимание, что вам нужно передать каталог, а не файл. Когда я выполняю:

testprog tmp/file1.txt

Я получил:

Cannot open directory 'tmp/file1.txt'

Это потому, что это файл, а не каталог (хотя, если вы хитрый, вы можете попытаться использовать diropen(dirname(argv[1])), если первоначальный diropen не работает).


(a) Теперь это исправлено, но, поскольку этот ответ был принят, я предполагаю, что это была проблема того, что вы проходили.

person paxdiablo    schedule 24.08.2010
comment
я имел в виду, что было ... вместо pDir = opendir (жесткое кодирование пути) мы можем поставить pDir = opendir (args [1]), который вводит пользователь? - person Vinod K; 24.08.2010
comment
Как избежать попадания в [.] И [..]? - person jaytj95; 02.10.2014
comment
@ jaytj95, вы здесь не пересекаете иерархию, вы просто делаете один уровень. Но логика будет аналогичной. В цикле просто strcmp pDirent->d_name против элементов, которые вы хотите игнорировать, и только printf / обход для остальных. - person paxdiablo; 22.04.2020

Некоторые отзывы о сегменте кода, хотя по большей части он должен работать ...

void main(int c,char **args)
  • int main - стандарт определяет main как возвращающий int.
  • c и args обычно называются argc и argv, уважительно, но вы можете называть их как угодно

...

{
DIR *dir;
struct dirent *dent;
char buffer[50];
strcpy(buffer,args[1]);
  • Здесь происходит переполнение буфера: если args[1] длиннее 50 байт, buffer не сможет его удержать, и вы запишете в память, чего не должны. Я не вижу причин для копирования буфера здесь, поэтому вы можете обойти эти проблемы, просто не используя _12 _...

...

dir=opendir(buffer);   //this part

Если это возвращается NULL, это может быть по нескольким причинам:

  • Каталог не существует. (Правильно ли вы ввели? Было ли в нем пробел, и вы набрали ./your_program my directory, что не удастся, потому что оно пытается opendir("my"))
  • У вас нет прав доступа к каталогу
  • Недостаточно памяти. (Это маловероятно.)
person Thanatos    schedule 24.08.2010

Параметры, передаваемые исполняемому файлу программы C, представляют собой не что иное, как массив строк (или символьный указатель), поэтому для этого входного параметра уже была бы выделена память до того, как ваша программа получит доступ к этим параметрам, поэтому нет необходимости выделять буфер, и таким образом вы можете также избегайте кода обработки ошибок в вашей программе (уменьшите вероятность segfault :)).

person Anil Vishnoi    schedule 24.08.2010

Вот простой способ реализовать команду ls с помощью c. Для запуска используйте например ./xls /tmp

    #include<stdio.h>
    #include <dirent.h>
    void main(int argc,char *argv[])
    {
   DIR *dir;
   struct dirent *dent;
   dir = opendir(argv[1]);   

   if(dir!=NULL)
      {
   while((dent=readdir(dir))!=NULL)
                    {
        if((strcmp(dent->d_name,".")==0 || strcmp(dent->d_name,"..")==0 || (*dent->d_name) == '.' ))
            {
            }
       else
              {
        printf(dent->d_name);
        printf("\n");
              }
                    }
       }
       close(dir);
     }
person Vijay S B    schedule 25.07.2016