LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
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 11-26-2018, 08:52 PM   #1
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Hacking code: direct assignment 2d char ** array works only for one condition.


I am trying to "fix" some code in an epplet, for e16, it only reads in one directory, not recursive, so I "fixed" that with a hack, but it only works when I am not reading a directory that has sub-directories.

the first 3 functions are off of the app E-Slides,
randomize_file_list
sort_file_list
dirscan

the modded, and hacked to get it to work using malloc for the 2d array, I globalized for 2 vars.

listdir
getAmount
printNames
main

are mine.


when I try to print out a dir and sub dir it seg faults in the print function. name copy is NULL only when reading in sub-directories, then direct assignment.

the size count matches on both single directory , and directory with sub-directories. using find [path type] | wc -l . I get the same amount of files that this says I have gotten.

I just do not understand why it works with one and not the other.

any questions let me know.
thanks.!


Code:
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>


#define randomize 1

unsigned long i = 0, g = 0;



static char ** randomize_file_list(char **names, unsigned long len)
{
	printf("random len %ld\n", len);
   int                 r;
   unsigned long       i;
   char               *tmp;

   for (i = 0; i < len - 1; i++)
     {
		 
	r = (int)((len - i - 1) * ((float)rand()) / (RAND_MAX + 1.0)) + i + 1;
	tmp = names[i];
	names[i] = names[r];
	names[r] = tmp;
	//printf("%s\n", names[r]);
     }
     printf("r = %d, i = %ld\n",r,i);
   return (names);
}

static char ** sort_file_list(char **names, unsigned long len)
{printf("ordered\n");
   unsigned long       i;
   unsigned char       done = 0;

   while (!done)
     {
	done = 1;
	for (i = 0; i < len - 1; i++)
	  {
	     if (strcmp(names[i], names[i + 1]) > 0)
	       {
		  char               *tmp;

		  tmp = names[i];
		  names[i] = names[i + 1];
		  names[i + 1] = tmp;
		  done = 0;
	       }
	  }
     }
   return (names);
}
//taken from epplets E-Slides
static char       **
dirscan(char *dir, unsigned long *num)
{
   unsigned long       i, dirlen;
   DIR                *dirp;
   char              **names;
   struct dirent      *dp;
   struct stat         filestat;
   char                fullname[1024];

   printf("dirscan(\"%s\", %8p) called.\n", dir, num);

   if ((!dir) || (!*dir))
     {
	*num = 0;
	return ((char **)NULL);
     }
   dirp = opendir(dir);
   if (!dirp)
     {
	*num = 0;
	return ((char **)NULL);
     }
   /* count # of entries in dir (worst case) */
   for (dirlen = 0; (dp = readdir(dirp)); dirlen++);
   printf(" -> Got %ld entries.\n", dirlen);
   if (!dirlen)
     {
	closedir(dirp);
	*num = 0;
	return ((char **)NULL);
     }
   names = (char **)malloc(dirlen * sizeof(char *));
   printf(" -> Storing names at %8p.\n", names);

   if (!names)
     {
	*num = 0;
	return ((char **)NULL);
     }
   rewinddir(dirp);
   for (i = 0; (dp = readdir(dirp));)
     {
	if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
	  {
	     snprintf(fullname, sizeof(fullname), "%s/%s", dir, dp->d_name);
	    // printf(" -> About to stat() %s\n", fullname);
	     if (stat(fullname, &filestat))
	       {
		  printf(" -> Couldn't stat() file %s -- %s\n", dp->d_name, strerror(errno));
	       }
	     else
	       {
		  if (S_ISREG(filestat.st_mode))
		    {
		   //    printf(" -> Adding name \"%s\" at index %ld (%8p)\n", dp->d_name, i, names + i);
		       names[i] = strdup(dp->d_name);
		       i++;
		    }
		  else if (S_ISDIR(filestat.st_mode))
		    {
		       /* Recurse directories here at some point, maybe? */
		    }
	       }
	  }
     }

   if (i < dirlen)
     {
	dirlen = i;
     }
   if (!dirlen)
     {
	closedir(dirp);
	*num = 0;
	return ((char **)NULL);
     }
   closedir(dirp);
   *num = dirlen;
   names = (char **)realloc(names, dirlen * sizeof(char *));
   printf(" -> Final directory length is %lu.  List moved to %8p\n", *num, names);

   if (randomize)
     {
	randomize_file_list(names, dirlen);
     }
   else
     {
	sort_file_list(names, dirlen);
     }
   return (names);
}

static char       **
listdir(char *dir) //, int indent, unsigned long *num)
{
    DIR *dirp;
    struct dirent *entry;
    char **names;
    char fullname[1024];
     
   names = (char **)malloc(i * sizeof(char *));
   //printf(" -> Storing names at %8p.\n", names);
	
    if (!(dirp = opendir(dir)))
        return  ((char **)NULL);

    while ((entry = readdir(dirp)) != NULL) {
        if (entry->d_type == DT_DIR) {
          //  char path[1024];
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
		snprintf(fullname, sizeof(fullname), "%s/%s", dir, entry->d_name);

		//printf("%*s[%s]\n", indent, "", entry->d_name);
	
        	//listdir(path); 
		
                listdir(fullname); 
        } else {
           // printf("%s - %s\n",path , entry->d_name);
             names[g] = strdup(entry->d_name);
	     g++;
        }
    }
            
    closedir(dirp);
     
	if (randomize)
     {
	randomize_file_list(names, i);
     }
   else
     {
	sort_file_list(names, i);
     }
   return (names);
  
}

 //get total files to know how much to malloc 2d char array

void getAmount(const char *name) //, unsigned long *num)
{
    DIR *dirp;
    struct dirent *entry;
    unsigned long dirlen;
	
	   if (!(dirp = opendir(name)))
       {
		   printf("cannot open dir.\n");
		   exit(1);
	   }
 
    while ((entry = readdir(dirp)) != NULL) {
        if (entry->d_type == DT_DIR) {
            char path[1024];
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
            snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
         //  printf("%*s[%s]\n", indent, "", entry->d_name);
            getAmount(path); //, num );
           // i++;
        } else {
          
           
          i++;
        }
    }
    
    
    closedir(dirp);
   
     
}

void printNames(char *s[], unsigned long size)
{
	printf("Print names %s : %ld\n", *s,size);
	
	for (int a = 0; a < size ;a++)
		printf("%s\n", s[a]);
	
}
int main (int argc, char **argv)
{
	char *path;
	unsigned long size;
	char **ImageNames;
	char **nameofImages;
		
	if(argc < 2)
	{
		printf("no path.\n");
		return EXIT_FAILURE;
	}
	
	if (!strcmp(argv[1], "-p"))
	{
		path = strdup(argv[2]);
		//ImageNames = dirscan(path, &size);
		getAmount(path);  
		
		//direct assignment only
		//works on dir without 
		//sub-directories. 
		nameofImages = listdir(path);  		
	}
	else
	{
		printf("could not get files.\n");
		return EXIT_FAILURE;
	}
	printf("i = %ld\n", i);
	printf("g = %ld\n", g);
	printf("size = %ld\n", size);
	
	//printNames(ImageNames, size);
	
	printf("\n\n\n\n\n\n");
	
	
	
		printNames(nameofImages, i );
				
		printf("i = %ld\n", i);
		printf("size = %ld\n", size);
	
	return 0;
}

Last edited by BW-userx; 11-26-2018 at 09:13 PM.
 
Old 11-27-2018, 08:36 AM   #2
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Original Poster
Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
I am so under thinking this, wanting to try and do the lest amount to get it to work. grrr I got to separate more then I am.
Code:
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>


//global to not reset count to zero
//in recursive function
int i = 0, b = 0;
int getcount = 1;


//get total files to know how much to malloc 2d char array

void getAmount(const char *name, int indent) 
{
    DIR *dirp;
    struct dirent *entry;
   char path[1024];
	
	   if (!(dirp = opendir(name)))
       {
		   printf("cannot open dir.\n");
		   exit(1);
	   }
 
  
    while ((entry = readdir(dirp)) != NULL) {
        if (entry->d_type == DT_DIR) {
           
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
            snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
         
            getAmount(path, indent + 2);
        } else {
        
            
            i++;
        }
    }
   closedir(dirp);
 }

char ** listdir(const char *name, char *names[], int indent)
{
    DIR *dir;
    struct dirent *entry;
    
        if (!(dir = opendir(name)))
           return  ((char **)NULL);
 
  
  
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_DIR) {
            char path[1024];
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
            snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
         
            listdir(path, names, indent + 2);
        } else {
		 
          
            names[b] = strdup(entry->d_name);
            b++;
        }
    }
    closedir(dir);
    
    return (names);
}

int main(int argc, char **argv) {
	
	
	char *path;
	char **gotNames;
	char **names;
	int g; 
	
	if(argc < 2)
	{
		printf("no path.\n");
		return EXIT_FAILURE;
	}
	
	if (!strcmp(argv[1], "-p"))
	{
		path = strdup(argv[2]);
		getAmount(path,0);
		names = (char **)malloc(i * sizeof(char *));
		gotNames =	listdir(path,names,0);  	
			
	}
	else
	{
		printf("could not get files missing -p.\n");
		return EXIT_FAILURE;
	}
	
	
	 
 
	for(g = 0; g < i; g++) {
		printf("%s\n",gotNames[g]);
	}
	  
		printf("howmany %d\n", i);
	
    
    return 0;
}
now I got to fit it into the other batch of code to see if I can get it to work in that.

Last edited by BW-userx; 11-27-2018 at 08:44 AM.
 
  


Reply



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
Returning char pointer from function which has array of char pointer srinietrx Programming 3 10-30-2015 03:55 AM
How do I point a char pointer to a part of another char array? trist007 Programming 8 11-06-2010 07:56 PM
scanf reading newline into char array while reading 1 char at a time austinium Programming 6 09-26-2010 11:27 PM
C++ help Dynamic array and "invalid conversion from ‘char’ to ‘char*’" heathf Programming 2 04-25-2009 09:20 PM
using OR condition in if condition Fond_of_Opensource Linux - Newbie 2 10-20-2006 12:34 AM

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

All times are GMT -5. The time now is 11:20 PM.

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
Open Source Consulting | Domain Registration