folder parsing (newbie)problem

O

oswald.harry

hi
i am learning to parse directory using dirent.h (using gcc of cygwin
as compiler)and tried to make an array of names of .png files in a
directory
here my problem is with accessing a char* []
I wrote this function

int parsedirectory(char * dirname){
struct dirent **filelist = {0};
char * directory =dirname;
int fcount = -1;
int i = 0;
fcount = scandir(directory, &filelist, 0, alphasort);

if(fcount < 0) {
perror(directory);
return 1;
}

int pngcnt;
pngcnt=0;
for(i = 0; i < fcount; i++) {
//i want to check if filename has a .png in it
if(strstr(filelist->d_name,".png")!=NULL){
++jpgcnt;
}

}
printf("png imgs:%d\n",pngcnt);//this shows totalnumber of .pngs

//then I can create a filenames array of size pngcnt

char* filenames[pngcnt];

//then i want to strcat the foldername with the imagename and add it
to the array
//so each entry in the array will be a string like "F:\code\c\testparse
\man1.png"

//but here i am stuck since the value fcount can't be used to //index
this array
//i tried like this

char fldr[strlen(dirname)];
strcpy(fldr,dirname);
strcat(fldr,"\\");
int j;//this i use to index into filenames[]
j=0;
for(i=0;i<fcount;i++){
if(strstr(filelist->d_name,".png")!=NULL){
char* name; //to make full name of a file
char fldrtemp[strlen(fldr)];
strcpy(fldrtemp,fldr);//so that strcat will not chang fldr
name=strcat(fldrtemp,filelist->d_name);
pngfilenames[j++]=name;
}
}

}

my problem is that when i try to iterate thru pngfilenames using
for(i=0;i<pngcnt;i++){
printf("%s\n",pngfilenames);
}

i get something like
D"
D"
D"
D"
not full path imagefilenames as expected!!
i am not sure if this is the right way..my c learning is in its
infancy so if

anyone can suggest a right way i will be grateful
 
P

Pravin Paratey

On Jan 22, 1:13 pm, (e-mail address removed) wrote:
for(i=0;i<fcount;i++){
if(strstr(filelist->d_name,".png")!=NULL){
char* name; //to make full name of a file
char fldrtemp[strlen(fldr)];
strcpy(fldrtemp,fldr);//so that strcat will not chang fldr
name=strcat(fldrtemp,filelist->d_name);
pngfilenames[j++]=name;
}

<snip>

Declare fldrtemp as

char *fldrtemp = new char[strlen(fldr)]; // or malloc

What's happening is all entries in pngfilenames[] array is pointing to
the same string address. Remember to free the memory when you're done.
 
M

Mark Bluemel

Pravin said:
On Jan 22, 1:13 pm, (e-mail address removed) wrote:
for(i=0;i<fcount;i++){
if(strstr(filelist->d_name,".png")!=NULL){
char* name; //to make full name of a file
char fldrtemp[strlen(fldr)];
strcpy(fldrtemp,fldr);//so that strcat will not chang fldr
name=strcat(fldrtemp,filelist->d_name);
pngfilenames[j++]=name;
}

<snip>

Declare fldrtemp as

char *fldrtemp = new char[strlen(fldr)]; // or malloc


If you're writing in standard C you can't use the syntax you've shown
above.

1) new is not part of standard C syntax.
2) "//" for comments is only part of the language at C99, though it is
supported by some compilers at earlier levels.
 
B

Ben Bacarisse

i am learning to parse directory using dirent.h (using gcc of cygwin
as compiler)and tried to make an array of names of .png files in a
directory
here my problem is with accessing a char* []

I can only talk about the C issues. I don't know the directory
functions you are using so I will just assume all that is OK.
I wrote this function

There is quite a lot and it is a bit messy. I will point a few
problems but I may well have missed others. Better layout would help
your readers.
int parsedirectory(char * dirname){
struct dirent **filelist = {0};
char * directory =dirname;
int fcount = -1;
int i = 0;
fcount = scandir(directory, &filelist, 0, alphasort);

if(fcount < 0) {
perror(directory);
return 1;
}

int pngcnt;
pngcnt=0;
for(i = 0; i < fcount; i++) {
//i want to check if filename has a .png in it
if(strstr(filelist->d_name,".png")!=NULL){
++jpgcnt;
}

}
printf("png imgs:%d\n",pngcnt);//this shows totalnumber of .pngs

//then I can create a filenames array of size pngcnt

char* filenames[pngcnt];


What do you plan to do with this array? Since it is local, you can't
ever return (a pointer to) it from this function. A more flexible
function would be able to return the array of names found and that
will require an array with a lifetime longer than a local variable
like this (i.e. a malloc'd array and contents).
//then i want to strcat the foldername with the imagename and add it
to the array
//so each entry in the array will be a string like "F:\code\c\testparse
\man1.png"

//but here i am stuck since the value fcount can't be used to //index
this array
//i tried like this

char fldr[strlen(dirname)];
strcpy(fldr,dirname);
strcat(fldr,"\\");

You made fldr only big enough for the letters in dirname. It must be
big enough to hold the terminating null as well as the \ you then add.
int j;//this i use to index into filenames[]
j=0;
for(i=0;i<fcount;i++){
if(strstr(filelist->d_name,".png")!=NULL){
char* name; //to make full name of a file
char fldrtemp[strlen(fldr)];


Not big enough. You must count the null but also the extra stuff you
are about to add (the d_name).
strcpy(fldrtemp,fldr);//so that strcat will not chang fldr
name=strcat(fldrtemp,filelist->d_name);
pngfilenames[j++]=name;


Here you are setting each array entry to point to a string which will
disappear when the loop body ends which is immediately! You need to
allocate storage for the string using malloc.

The function should new free everything it has allocated. A read of
the C FAQ would help you, I think: http://c-faq.com/
 
N

Nick Keighley

i am learning to parse directory using dirent.h (using gcc of cygwin
as compiler)

technically direct.h is off-topic. If your problem is with
dirent.h you need to take it to a unix news group.

But I'm not sure your problem is dirent.h...

and tried to make an array of names of .png files in a
directory
here my problem is with accessing a char* []
I wrote this function

int parsedirectory(char * dirname){
 struct dirent **filelist = {0};

you've initialised this as if it were a struct.
It's not it's a ptr.

use
struct dirent **filelist = NULL;
 char * directory =dirname;
 int fcount = -1;
 int i = 0;
 fcount = scandir(directory, &filelist, 0, alphasort);

 if(fcount < 0) {
  perror(directory);
  return 1;
 }

 int pngcnt;

you can't mix declarations with statements in C89
(the most portable standard).
 pngcnt=0;
 for(i = 0; i < fcount; i++)  {
//i want to check if filename has a .png in it
if(strstr(filelist->d_name,".png")!=NULL){
   ++jpgcnt;
  }

 }
printf("png imgs:%d\n",pngcnt);//this shows totalnumber of .pngs

//then I can create a filenames array of size pngcnt

char* filenames[pngcnt];


this is an array of char*. Somewhere you must allocate some memory
for these pointers to point to. You don't.

//then i want to strcat the foldername with the imagename and add it
to the array
//so each entry in the array will be a string like
// "F:\code\c\testparse\man1.png"

beware of // comments. They screw up in postings
//but here i am stuck since the value fcount can't be used to
//index this array

I've no idea what this means.

//i tried like this

char fldr[strlen(dirname)];

you can't use strlen() as an array dimension. Does this
even compile? If so you are using a weird compiler.
(maybe gcc not in ANSI mode). Assume dirname is six characters.
Then strlen is 6.
strcpy(fldr,dirname);

oops! dirname actually occupies *7* bytes (one for the nul
char).
strcat(fldr,"\\");

oops!! you now have 8 bytes in your 6 byte array.
Use malloc()

char *fldr = malloc (strlen(dirname) + 2);
if (fldr == 0) abort();
int j; //this I use to index into filenames[]
j=0;
for(i=0;i<fcount;i++){
  if(strstr(filelist->d_name,".png")!=NULL){
     char* name; //to make full name of a file
     char fldrtemp[strlen(fldr)];
     strcpy(fldrtemp,fldr);//so that strcat will not chang fldr
     name=strcat(fldrtemp,filelist->d_name);


more of the same. Also you point name at fldrtemp[]
which disappears at the end of the for loop.
And then probably gets reused on the next iteration.
Use malloc().

char* name = malloc (strlen(fldr) + strlen(filelist->d_name) +
1);
strcpy (fldrtemp, fldr);
name = strcat (fldrtemp,filelist->d_name);

/* or replace the last two lines with
sprintf (name, "%s%s", fldr, filelist->d_name);
     pngfilenames[j++]=name;
   }

}
}

my problem is that when i try to iterate thru pngfilenames using
for(i=0;i<pngcnt;i++){
  printf("%s\n",pngfilenames);

}

i get something like
D"
D"
D"
D"
  not full path imagefilenames as expected!!
i am not sure if this is the right way..my c learning is in its
infancy so if

anyone can suggest a right way i will be grateful


a general suggestion is break the program down into
smaller steps. Write a program then returns all the files
in the directory. Print them out. Does that look ok?
Filter out the pngs. Print them

<OT>
you do know scandir() will do this for you?
</OT>

turn up your compiler warnings. If it's gcc
use
gcc -W -Wall -ansi -pedantic

and maybe -O2

you should probably read up on pointers and on malloc().

char *name[23];

defines an array of pointers. It *does not* allocate
any memory for the pointers to point at.
 
K

Keith Thompson

Pravin Paratey said:
Declare fldrtemp as

char *fldrtemp = new char[strlen(fldr)]; // or malloc

What's happening is all entries in pngfilenames[] array is pointing to
the same string address. Remember to free the memory when you're done.

Apart from the fact that "new" is C++, not C, you're not allocating
space to hold the terminating '\0'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top