View Full Version : Implement ls command in c++
adityakavoor
March 5th, 2008, 01:52 PM
I wrote a C++ code for implementing ls command.
#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include<iostream.h>
int main(int argc, char *argv[])
{
DIR *dp;
dirent *d;
if(dp = opendir(argv[1]) != NULL)
perror("opendir");
while(d = readdir(dp) != NULL)
{
if(!strcmp(d->d_name,".") || !strcmp(d->d_name,".."))
continue;
cout << d->d_name << endl;
}
}
I get the following error
aditya@ubuntu:~$ g++ lsr.cpp -Wno-deprecated
lsr.cpp: In function ‘int main(int, char**)’:
lsr.cpp:11: error: cannot convert ‘bool’ to ‘DIR*’ in assignment
lsr.cpp:14: error: cannot convert ‘bool’ to ‘dirent*’ in assignment
Any Idea ??
WW
March 5th, 2008, 01:59 PM
!= has higher precedence (http://www.cppreference.com/operator_precedence.html) than =. Put parentheses around the assignment, then compare to NULL.
adityakavoor
March 5th, 2008, 02:04 PM
Thanks WW. :popcorn:
adityakavoor
March 5th, 2008, 02:40 PM
Problem Implementing Recursive listing (ls -r)
#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include<iostream.h>
void recursive_listing(char *ptr)
{
DIR *dp;
dirent *d;
if((dp = opendir(ptr)) == NULL)
perror("opendir");
while((d = readdir(dp)) != NULL)
{
if(!strcmp(d->d_name,".") || !strcmp(d->d_name,".."))
continue;
if (d->d_type && DT_DIR)
{
cout << d->d_name << ":" << endl;
recursive_listing(d->d_name);
}
else
cout << d->d_name << endl;
}
return;
}
int main(int argc, char *argv[])
{
recursive_listing(argv[1]);
}
I dont get any errors.
Program doesnt work. :(
Any Idea ??
WW
March 5th, 2008, 02:50 PM
The variables dp and d are global, so your function is not reentrant; the variables get initialized with each call to recursive_listing(). Try making them local in recursive_listing().
P.S. You should also call closedir(dp) before you return from recursive_listing.
adityakavoor
March 5th, 2008, 02:54 PM
Yep, I tried doing that.
No change in output.
Only the first entry in the directory is listed. Not all.
adityakavoor
March 5th, 2008, 03:00 PM
closedir(dp) didnt work either.
Is the condition for checking for the Directory file type correct ??
if ( d->d_type && DT_DIR )
Also the output : The inner directories are not opened
aditya@ubuntu:~$ ./a.out Desktop/
cars:
opendir: No such file or directory
Segmentation fault (core dumped)
I have a "cars" directory in Desktop
WW
March 5th, 2008, 03:07 PM
Change && to &.
adityakavoor
March 5th, 2008, 03:11 PM
Still no :( :(
btw what is the difference between & and && ??
WW
March 5th, 2008, 03:13 PM
Also, you need to pass the full path name when you recurse. As it is, opendir tries to open all the files in the current working directory.
WW
March 5th, 2008, 03:16 PM
btw what is the difference between & and && ??
http://cboard.cprogramming.com/showthread.php?t=85130
adityakavoor
March 5th, 2008, 03:17 PM
Also, you need to pass the full path name when you recurse. As it is, opendir tries to open all the files in the current working directory.
Oh yes.
What is the solution for that ?
EDIT : but in argv[1] I just gave Desktop and not /home/aditya/Desktop :confused:
WW
March 5th, 2008, 03:29 PM
Sorry, I shouldn't have said full. You can give a path relative to the current directory when you recurse. For example, Desktop/cars.
adityakavoor
March 5th, 2008, 03:32 PM
Even then, when I recurse, "cars" is passed as an argument to opendir( ) and not Desktop/cars.
Correct me if I am wrong.
WW
March 5th, 2008, 03:36 PM
EDIT:
opendir should be given "Desktop/cars". You have to modify your program to pass the correct name.
adityakavoor
March 5th, 2008, 03:38 PM
OK. I'l be back with the modified code. Thanks for now
adityakavoor
March 6th, 2008, 03:03 AM
Finally It worked. Here is the modified code.
if (d->d_type & DT_DIR)
{
cout << d->d_name << ":" << endl;
strcpy(temp,ptr);
strcat(temp,"/");
strcat(temp,d->d_name);
recursive_listing(temp);
}
the_unforgiven
March 6th, 2008, 08:13 AM
Finally It worked. Here is the modified code.
if (d->d_type & DT_DIR)
{
cout << d->d_name << ":" << endl;
strcpy(temp,ptr);
strcat(temp,"/");
strcat(temp,d->d_name);
recursive_listing(temp);
}
The code is not C++ at all - except for using cout and endl - it's just C with syntactic sugar of C++.
You might as well use printf() and '\n' for them.
I could understand if you were using std::string for handling all the string manipulation - in fact, that would've been much simpler too.
dwhitney67
March 6th, 2008, 09:05 AM
The code is not C++ at all - except for using cout and endl - it's just C with syntactic sugar of C++.
You might as well use printf() and '\n' for them.
I could understand if you were using std::string for handling all the string manipulation - in fact, that would've been much simpler too.
I agree 100%.
Here's a simple C++ implementation I came up with long ago:
void listAllFiles( const std::string &dirName )
{
DIR *dirp = opendir( dirName.c_str() );
if ( dirp )
{
struct dirent *dp = NULL;
while ( (dp = readdir( dirp )) != NULL )
{
std::string file( dp->d_name );
if ( file == "." || file == ".." ) // skip these
continue;
if ( dp->d_type & DT_DIR )
{
// found a directory; recurse into it.
string filePath = dirName + "/" + file;
listAllFiles( filePath );
}
else
{
// regular file found
std::cout << "filename is: " << file << std::endl;
}
}
closedir( dirp );
}
}
adityakavoor
March 6th, 2008, 12:48 PM
Thanks dwhitney67 and the_unforgiven for your comments.
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.