LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-21-2008, 01:40 PM   #1
babag
Member
 
Registered: Aug 2003
Posts: 368

Rep: Reputation: 30
c++ - how to find first file in directory in linux system


all the examples i've seen seem to be for windows and are a
bit different than what i need. also, findfirstfile is not
in the textbook i bought to use as reference.

i need to find the first file in a directory so i can perform
a loop for processing. all of the files in the directory will
be of the same type and have the same name except that each
file is numbered. if i can find the first file in the directory,
i should be able to parse the name and increment the numbers in
the loop to move through the directory.

any tips on finding the first file's name?

thanks,
BabaG
 
Old 05-21-2008, 04:27 PM   #2
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,014

Rep: Reputation: 115Reputation: 115
look at dirent.h:
http://opengroup.org/onlinepubs/0079.../dirent.h.html

For more portability and C++-style, try boost filesystem:
http://www.boost.org/doc/libs/1_35_0.../doc/index.htm

It's a better idea to iterate through the directory using dirent rather than parse the name. You don't run the risk of trying to process a file that doesn't exist that way.

Actually, it's probably even better to write the program to process a single file, then use a simple bash script to run it on all the files in a directory.YMMV

Last edited by tuxdev; 05-21-2008 at 04:28 PM.
 
Old 05-22-2008, 01:55 AM   #3
babag
Member
 
Registered: Aug 2003
Posts: 368

Original Poster
Rep: Reputation: 30
thanks tuxdev. found this in searches based off your link:
Code:
/* print files in current directory in reverse order */

#include <dirent.h>

main(){

    struct dirent **namelist;

    int n;

    n = scandir(".", &namelist, 0, alphasort); 

    if (n < 0) 
        perror("scandir"); 
    else { 

        while(n--) { 
            printf("%s\n", namelist[n]->d_name); 
            free(namelist[n]); 
        } 

        free(namelist); 
    } 
}
does almost exactly what i need so i think i can adapt
it if i can get this working. it produces errors when
i compile it. i get:

perror was not declared in this scope
printf was not declared in this scope
free was not declared in this scope
free was not declared in this scope

how do i properly declare these? or do i simply have
the wrong commands there for c++?

edit:
it was pointed out to me elsewhere that this is c code.

added:

#include <cstdio>
int main()
return 0
Code:
/* print files in current directory in reverse order */

#include <cstdio>
#include <dirent.h>

int main(){

    struct dirent **namelist;

    int n;

    n = scandir(".", &namelist, 0, alphasort); 

    if (n < 0) 
        perror("scandir"); 
    else { 

        while(n--) { 
            printf("%s\n", namelist[n]->d_name); 
            free(namelist[n]); 
        } 

        free(namelist); 
    } 

    return 0;

}
and am now left with only:

free was not declared in this scope
free was not declared in this scope

how do i declare 'free'? or is it a missing header?

thanks again,
BabaG

thanks,
BabaG

Last edited by babag; 05-22-2008 at 12:03 PM.
 
Old 05-23-2008, 08:21 PM   #4
babag
Member
 
Registered: Aug 2003
Posts: 368

Original Poster
Rep: Reputation: 30
this is what i've gotten to work:
Code:
#include <algorithm>					//added from computing.net tip
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>

using namespace std;

/*function... might want it in some class?*/
int getdir (string dir, vector<string> &files)
{

    DIR *dp;
    struct dirent *dirp;

    if((dp  = opendir(dir.c_str())) == NULL) {
        cout << "Error(" << errno << ") opening " << dir << endl;
        return errno;
    }

    while ((dirp = readdir(dp)) != NULL) {
        files.push_back(string(dirp->d_name));
    }

    closedir(dp);
    sort (files.begin(), files.end());			//added from computing.net tip

    return 0;
}

int main()
{

    string firstfile = "";

//    string dir = string(".");				//this directory
    string dir = string("/home/babag/Documents/Scripts/receiving");
    vector<string> files = vector<string>();

    getdir(dir,files);

    firstfile = files[2];				//print first file after (.) and (..)
    cout << firstfile << endl;

/*this for loop prints directory contents*/
//    for (unsigned int i = 2;i < files.size();i++) {	//i=0 includes . and ..; i=1 includes ..; i=2 starts on first file
//        cout << files[i] << endl;			//print each file in directory
//	  cout << files[0] << endl;			//print first file in directory (.) or 'this directory' symbol
//    }


    return 0;
}
the only things that are awkward for me are that there is not
an included routine for skipping over . and .. in the return,
and that there is an upper/lowercase issue in the sort.

if the target directory for this code has files of mixed case,
it produces two lists, one for uppercase, another for lowercase
rather than mixing them together.

thanks for the help i received on this and in general. coding
is not my thing really and this has been a struggle for me but
people here have been both patient and helpful.

thanks again,
BabaG
 
Old 05-23-2008, 11:16 PM   #5
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,508

Rep: Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811
Quote:
Originally Posted by babag View Post
the only things that are awkward for me are that there is not
an included routine for skipping over . and .. in the return,
and that there is an upper/lowercase issue in the sort.

if the target directory for this code has files of mixed case,
it produces two lists, one for uppercase, another for lowercase
rather than mixing them together.
That's because the sort for strings compares the ascii values by default, you can pass in your own comparison function to sort:
Code:
#include <cctype>

bool compare_ignore_case(const string &str1, const string str2) {
    string upcased1, upcased2;
    transform(str1.begin(), str1.end(), upcased1.begin(), ::toupper); 
    transform(str2.begin(), str2.end(), upcased2.begin(), ::toupper);

    return upcased1 < upcased2;
}

...
sort (files.begin(), files.end(), compare_ignore_case);
...
For the . and .. you could use remove_if:
Code:
bool is_dotfile(const string &filename) {
    return filename == "." || filename == "..";
}
...
vector<string>::iterator new_end =
	remove_if(files.begin(), files.end(), is_dotfile);
files.erase(new_end, files.end());
...
 
  


Reply

Tags
look


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How do i find the biggest file in my directory? anandv_1234 Linux - Newbie 11 12-21-2007 12:58 PM
find pattern in any file in directory sancho1980 Linux - Newbie 4 12-19-2006 08:14 AM
linux command error message bash: /usr/bin/find: No such file or directory sundaram123 Linux - General 8 04-02-2002 07:18 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:24 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration