Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Borderlands 4, tra divertimento e problemi tecnici
Recensione Borderlands 4, tra divertimento e problemi tecnici
Gearbox Software rilancia la saga con Borderlands 4, ora disponibile su PS5, Xbox Series X|S e PC. Tra le novità spiccano nuove abilità di movimento, un pianeta inedito da esplorare e una campagna che lascia al giocatore piena libertà di approccio
TCL NXTPAPER 60 Ultra: lo smartphone che trasforma la lettura da digitale a naturale
TCL NXTPAPER 60 Ultra: lo smartphone che trasforma la lettura da digitale a naturale
NXTPAPER 60 Ultra è il primo smartphone con tecnologia NXTPAPER 4.0 per il display, un ampio IPS da 7,2 pollici. Con finitura anti-riflesso, processore MediaTek Dimensity 7400, fotocamera periscopica e modalità Max Ink per il detox digitale, NXTPAPER 60 Ultra punta a essere il riferimento tra gli smartphone pensati per il benessere degli occhi.
Un fulmine sulla scrivania, Corsair Sabre v2 Pro ridefinisce la velocità nel gaming
Un fulmine sulla scrivania, Corsair Sabre v2 Pro ridefinisce la velocità nel gaming
Questo mouse ultraleggero, con soli 36 grammi di peso, è stato concepito per offrire un'esperienza di gioco di alto livello ai professionisti degli FPS, grazie al polling rate a 8.000 Hz e a un sensore ottico da 33.000 DPI. La recensione esplora ogni dettaglio di questo dispositivo di gioco, dalla sua agilità estrema alle specifiche tecniche che lo pongono un passo avanti
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 06-03-2013, 17:12   #1
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
[C] Calcolare dimensione directory

Ciao a tutti questo è il mio codice che mi permette di leggere il contenuto di una directory

Codice:
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>



int main (void)
{
 DIR *directory;
 

 struct stat dim;
 struct dirent *dir;
 

 directory=opendir("H:/");


 if(directory!=NULL){
 while((dir= readdir(directory))!=NULL) {

    puts(dir->d_name);


  }
 }
  else{

    perror("Impossibile aprire destinazione!");
  }



 closedir(directory);

 system("pause");
 free(dir);
  return 0;
}

ora io ho due domande :

1) Come faccio a vedere(o calcolare) la dimensione di questa directory?
2) Se questa directory avesse altre cartelle come faccio a leggere anche il loro contenuto?


grazie come sempre a tutti in anticipo!
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 06-03-2013, 18:49   #2
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Puoi usare le primitive contenute in <sys/stat.h>.
Vale a dire, una volta ottenuto il nome del file, ne fai uno stat().

La stat() ti ritornera' le informazioni che ti servono, quali la dimensione del file, se il file e' un regolare/directory/link/... oltre che data di creazione, modifica, ...

Se il file e' regolare, sommi le dimensioni.
Se il file e' directory, la puoi scandire ricorsivamente (e' piu' facile, ma puoi ovviamente fare anche iterativamente)
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 06-03-2013, 19:44   #3
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Per Windows:






ScanDir.h
Codice:
#ifndef _MY_SCANDIR_
#define _MY_SCANDIR_

// Dati usati dalla funzione DirWalkRecurse
typedef struct
{
	TCHAR  szInitPath[_MAX_DIR];		// Path iniziale
	TCHAR  szCurrPath[_MAX_DIR];		// Path corrente
	TCHAR  szPathParent[_MAX_DIR];		// Path genitore di szCurrPath
	TCHAR  szCurrDir[_MAX_DIR];			// Path temporaneo; ci servirà per la ricerca dei files
	int    nDepth;						// Profondità
	BOOL   fRecurse;					// impostare a TRUE per ottenere la scansione delle sottodirectory. 
	TCHAR  szBuf[1024];					// Buffer per l'output formattato 
	int    nIndent;						// Contatore per l'indentazione 
	BOOL   fOk;							// Loop control flag 
	BOOL   fIsDir;						// Loop control flag 
	WIN32_FIND_DATA FindData;			// Informazioni sui file 
} DIRWALKDATA, *LPDIRWALKDATA;

void DirWalk (LPCTSTR pszRootPath, BOOL fRecurse, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA));

#endif
ScanDir.c
Codice:
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0]))

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>

#include <stdlib.h>
#include <stdio.h>

#include "ScanDir.h"

BOOL IsChildDir (WIN32_FIND_DATA *lpFindData)
{
	return
		(
			(lpFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
			(lpFindData->cFileName[0] != __TEXT('.'))
		);
}

BOOL FindNextChildDir (HANDLE hFindFile, WIN32_FIND_DATA *lpFindData)
{
	BOOL fFound = FALSE;
	do
	{
		fFound = FindNextFile(hFindFile, lpFindData);
	} while (fFound && !IsChildDir(lpFindData));
	
	return(fFound);
}

HANDLE FindFirstChildDir (LPTSTR szPath, WIN32_FIND_DATA *lpFindData)
{
	BOOL fFound;
	HANDLE hFindFile = FindFirstFile(szPath, lpFindData);

	if (hFindFile != INVALID_HANDLE_VALUE)
	{
		fFound = IsChildDir(lpFindData);
		if (!fFound)
			fFound = FindNextChildDir(hFindFile, lpFindData);
		
		if (!fFound)
		{
			FindClose(hFindFile);
			hFindFile = INVALID_HANDLE_VALUE;
		}
	}
	
	return(hFindFile);
}

void GetParentDirectory(LPCTSTR szPath, LPTSTR szParent)
{
	size_t nLen;
	nLen = _tcslen(szPath);

	_tcscpy(szParent, szPath);


	if ( szPath[0] == '\\' )
		return;

	while ( nLen > 0 )
	{
		if ( *(szParent + nLen-1) == '\\' )
		{
			*(szParent + nLen-1) = '\0';
			break;
		}

		--nLen;
	}
}

// Percorre la struttura della directory.
// Se il campo pDW->fRecurse è TRUE, percorre ricorsivamente anche le sottodirectory.
void DirWalkRecurse (LPDIRWALKDATA pDW, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA))
{
	HANDLE hFind;
	pDW->szCurrDir[0] = '\0';
	
	pDW->nDepth++;
	
	pDW->nIndent = 3 * pDW->nDepth;
	_stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent, __TEXT(""));

	
	// Imposta il buffer alla directory iniziale e chiama la funzione evento
	// fornita dall'utente.
	_tcscpy(&pDW->szBuf[pDW->nIndent], pDW->szCurrPath);

	if ( pfnOnChange )
		(*pfnOnChange)(pDW);
	//printf("pDW->szBuf -----> %s\n", pDW->szBuf);


	// Inizia a leggere il contenuto della directory iniziale
	_tcscpy(pDW->szCurrDir, pDW->szCurrPath);
	_tcscat(pDW->szCurrDir, __TEXT("\\*.*"));

	hFind = FindFirstFile( pDW->szCurrDir, &pDW->FindData);
	pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
	
	while (pDW->fOk)
	{
		pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
		if ( !pDW->fIsDir || (!pDW->fRecurse && IsChildDir(&pDW->FindData)) )
		{
			_stprintf(
				pDW->szBuf,
				pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"),
				pDW->nIndent, __TEXT(""),
				pDW->FindData.cFileName);

			// Per ogni file ( o sottodirectory ) trovato,
			// chiamiamo la funzione fornita dall'utente
			// passandogli i dati relativi tramite il puntatore alla struct pDW.
			if ( pfnOnChange )
				(*pfnOnChange)(pDW);
			//printf("pDW->szBuf -----> %s\n", pDW->szBuf);

		}
		pDW->fOk = FindNextFile(hFind, &pDW->FindData);
	}
	if (hFind != INVALID_HANDLE_VALUE)
		FindClose(hFind);
	
	// se fRecurse è TRUE, leggiamo ricorsivamente le sottodirectory
	if (pDW->fRecurse)
	{
		// Ottiene la prima directory figlia
		hFind = FindFirstChildDir( pDW->szCurrDir, &pDW->FindData );
		pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
		while (pDW->fOk)
		{
			// Passa alla directory figlia
			_tcscat(pDW->szCurrPath, __TEXT("\\"));
			_tcscat(pDW->szCurrPath, pDW->FindData.cFileName);

			DirWalkRecurse(pDW, pfnOnChange);

			// Ritorna alla directory genitore
			GetParentDirectory(pDW->szCurrPath, pDW->szPathParent);
			_tcscpy(pDW->szCurrPath, pDW->szPathParent);

			pDW->fOk = FindNextChildDir(hFind, &pDW->FindData);
		}
		
		if (hFind != INVALID_HANDLE_VALUE)
			FindClose(hFind);
	}
	pDW->nDepth--;
}

// Funzioni esportate
/////////////////////////////////////////////////////////////

// Il parametro pszRootPath è il percorso completo della directory da esaminare
// Il parametro fRecurse è un valore booleano che indica
// se vogliamo leggere anche le sottodirectory. Se impostato a FALSE, la funzione
// legge solo la directory passata nel parametro pszRootPath
// Il parametro pfnOnChange è un puntatore a una funzione evento che deve essere
// implementata dal client ( il programma che utilizza la DLL )

void DirWalk (LPCTSTR pszRootPath, BOOL fRecurse, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA))
{
	DIRWALKDATA DW;
	
	DW.szBuf[0] = '\0';
	DW.szCurrDir[0] = '\0';
	DW.szCurrPath[0] = '\0';
	DW.szInitPath[0] = '\0';
	DW.szPathParent[0] = '\0';

	// nDepth è usato per controllare l'indentazione. Il valore -1
	// fa si che il primo livello sia visualizzato allineato a sinistra
	DW.nDepth = -1;

	DW.fRecurse = fRecurse;

	_tcscpy(DW.szInitPath, pszRootPath);
	_tcscpy(DW.szCurrPath, pszRootPath);

	// Leggiamo il contenuto della directory passata nel parametro pszRootPath.
	// Se il parametro fRecurse è TRUE, leggiamo anche le sottodirectory
	DirWalkRecurse(&DW, pfnOnChange);
}
ScanDirClient.c
Codice:
#include <windows.h>

#include <stdio.h>
#include "scandir.h"

void CALLBACK OnChange(LPDIRWALKDATA pDW)
{
	printf("# -> %s\n", pDW->szBuf);
}

int main(int argc, char* argv[])
{
	if( argc < 2 )
		return -1;

	DirWalk(argv[1], TRUE, OnChange);

	return 0;
}
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 06-03-2013, 19:52   #4
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Per la dimensione della directory, su Windows, puoi utilizzare diverse api:

http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 06-03-2013, 20:37   #5
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Questo invece è l'esempio per Linux, tratto dal bel libro di W. Richard Stevens e Stephen A. Rago:



apue.h
Codice:
/* Our own header, to be included before all standard system headers */

#ifndef	_APUE_H
#define	_APUE_H

#if defined(SOLARIS)
#define _XOPEN_SOURCE	500	/* Single UNIX Specification, Version 2  for Solaris 9 */
#define CMSG_LEN(x)	_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)+(x))
#elif !defined(BSD)
#define _XOPEN_SOURCE	600	/* Single UNIX Specification, Version 3 */
#endif

#include <sys/types.h>		/* some systems still require this */
#include <sys/stat.h>
#include <sys/termios.h>	/* for winsize */
#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif
#include <stdio.h>		/* for convenience */
#include <stdlib.h>		/* for convenience */
#include <stddef.h>		/* for offsetof */
#include <string.h>		/* for convenience */
#include <unistd.h>		/* for convenience */
#include <signal.h>		/* for SIG_ERR */

#define	MAXLINE	4096			/* max line length */

/*
 * Default file access permissions for new files.
 */
#define	FILE_MODE	(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

/*
 * Default permissions for new directories.
 */
#define	DIR_MODE	(FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)

typedef	void	Sigfunc(int);	/* for signal handlers */

#if	defined(SIG_IGN) && !defined(SIG_ERR)
#define	SIG_ERR	((Sigfunc *)-1)
#endif

#define	min(a,b)	((a) < (b) ? (a) : (b))
#define	max(a,b)	((a) > (b) ? (a) : (b))

/*
 * Prototypes for our own functions.
 */
char	*path_alloc(int *);				/* {Prog pathalloc} */
long	 open_max(void);				/* {Prog openmax} */
void	 clr_fl(int, int);				/* {Prog setfl} */
void	 set_fl(int, int);				/* {Prog setfl} */
void	 pr_exit(int);					/* {Prog prexit} */
void	 pr_mask(const char *);			/* {Prog prmask} */
Sigfunc	*signal_intr(int, Sigfunc *);	/* {Prog signal_intr_function} */

int		 tty_cbreak(int);				/* {Prog raw} */
int		 tty_raw(int);					/* {Prog raw} */
int		 tty_reset(int);				/* {Prog raw} */
void	 tty_atexit(void);				/* {Prog raw} */
#ifdef	ECHO	/* only if <termios.h> has been included */
struct termios	*tty_termios(void);		/* {Prog raw} */
#endif

void	 sleep_us(unsigned int);			/* {Ex sleepus} */
ssize_t	 readn(int, void *, size_t);		/* {Prog readn_writen} */
ssize_t	 writen(int, const void *, size_t);	/* {Prog readn_writen} */
void	 daemonize(const char *);			/* {Prog daemoninit} */

int		 s_pipe(int *);					/* {Progs streams_spipe sock_spipe} */
int		 recv_fd(int, ssize_t (*func)(int,
		         const void *, size_t));/* {Progs recvfd_streams recvfd_sockets} */
int		 send_fd(int, int);				/* {Progs sendfd_streams sendfd_sockets} */
int		 send_err(int, int,
		          const char *);		/* {Prog senderr} */
int		 serv_listen(const char *);		/* {Progs servlisten_streams servlisten_sockets} */
int		 serv_accept(int, uid_t *);		/* {Progs servaccept_streams servaccept_sockets} */
int		 cli_conn(const char *);		/* {Progs cliconn_streams cliconn_sockets} */
int		 buf_args(char *, int (*func)(int,
		          char **));			/* {Prog bufargs} */

int		 ptym_open(char *, int);	/* {Progs3 ptyopen_streams ptyopen_bsd ptyopen_linux} */
int		 ptys_open(char *);			/* {Progs3 ptyopen_streams ptyopen_bsd ptyopen_linux} */
#ifdef	TIOCGWINSZ
pid_t	 pty_fork(int *, char *, int, const struct termios *,
		          const struct winsize *);		/* {Prog ptyfork} */
#endif

int		lock_reg(int, int, int, off_t, int, off_t); /* {Prog lockreg} */
#define	read_lock(fd, offset, whence, len) \
			lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define	readw_lock(fd, offset, whence, len) \
			lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
#define	write_lock(fd, offset, whence, len) \
			lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
#define	writew_lock(fd, offset, whence, len) \
			lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define	un_lock(fd, offset, whence, len) \
			lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))

pid_t	lock_test(int, int, off_t, int, off_t);		/* {Prog locktest} */

#define	is_read_lockable(fd, offset, whence, len) \
			(lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define	is_write_lockable(fd, offset, whence, len) \
			(lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)

void	err_dump(const char *, ...);		/* {App misc_source} */
void	err_msg(const char *, ...);
void	err_quit(const char *, ...);
void	err_exit(int, const char *, ...);
void	err_ret(const char *, ...);
void	err_sys(const char *, ...);

void	log_msg(const char *, ...);			/* {App misc_source} */
void	log_open(const char *, int, int);
void	log_quit(const char *, ...);
void	log_ret(const char *, ...);
void	log_sys(const char *, ...);

void	TELL_WAIT(void);		/* parent/child from {Sec race_conditions} */
void	TELL_PARENT(pid_t);
void	TELL_CHILD(pid_t);
void	WAIT_PARENT(void);
void	WAIT_CHILD(void);

#endif	/* _APUE_H */

scandir.c
Codice:
#include "apue.h"
#include <dirent.h>
#include <limits.h>
/* function type that is called for each filename */
typedef int Myfunc(const char *, const struct stat *, int);
static Myfunc     myfunc;
static int        myftw(char *, Myfunc *);
static int        dopath(Myfunc *);
static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;

int main(int argc, char *argv[])
{
    int     ret;
    if (argc != 2)
    {
        printf("usage: scandir <starting-pathname>");
        return -1;
    }
    
    ret = myftw(argv[1], myfunc);        /* does it all */
    ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
    if (ntot == 0)
        ntot = 1;       /* avoid divide by 0; print 0 for all counts */
    printf("regular files  = %7ld, %5.2f %%\n", nreg,
      nreg*100.0/ntot);
    printf("directories    = %7ld, %5.2f %%\n", ndir,
      ndir*100.0/ntot);
    printf("block special  = %7ld, %5.2f %%\n", nblk,
      nblk*100.0/ntot);
    printf("char special   = %7ld, %5.2f %%\n", nchr,
      nchr*100.0/ntot);
    printf("FIFOs          = %7ld, %5.2f %%\n", nfifo,
      nfifo*100.0/ntot);
    printf("symbolic links = %7ld, %5.2f %%\n", nslink,
      nslink*100.0/ntot);
    printf("sockets        = %7ld, %5.2f %%\n", nsock,
      nsock*100.0/ntot);
    exit(ret);
}

/*
 * Descend through the hierarchy, starting at "pathname".
 * The caller's func() is called for every file.
 */
#define FTW_F   1       /* file other than directory */
#define FTW_D   2       /* directory */
#define FTW_DNR 3       /* directory that can't be read */
#define FTW_NS  4       /* file that we can't stat */
static char *fullpath;      /* contains full pathname for every file */
static int                  /* we return whatever func() returns */
myftw(char *pathname, Myfunc *func)
{
    int len;
    //fullpath = path_alloc(&len);    /* malloc's for PATH_MAX+1 bytes */
    
    len = PATH_MAX * sizeof(char) + 1;
    fullpath = (char*)malloc(len);
    if ( !fullpath )
    {
		printf("Memoria insufficiente, addio!\n");
		return -1;
	}
    
    strncpy(fullpath, pathname, len);       /* protect against */
    fullpath[len-1] = 0;                    /* buffer overrun */
    return(dopath(func));
}

/*
 * Descend through the hierarchy, starting at "fullpath".
 * If "fullpath" is anything other than a directory, we lstat() it,
 * call func(), and return. For a directory, we call ourself
 * recursively for each name in the directory.
 */
static int                  /* we return whatever func() returns */
dopath(Myfunc* func)
{
    struct stat     statbuf;
    struct dirent   *dirp;
    DIR             *dp;
    int             ret;
    char            *ptr;
    if (lstat(fullpath, &statbuf) < 0) /* stat error */
        return(func(fullpath, &statbuf, FTW_NS));
    if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */
        return(func(fullpath, &statbuf, FTW_F));
     /*
      * It's a directory. First call func() for the directory,
      * then process each filename in the directory.
      */
    if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
        return(ret);
    ptr = fullpath + strlen(fullpath);      /* point to end of fullpath */
    *ptr++ = '/';
    *ptr = 0;
     if ((dp = opendir(fullpath)) == NULL)     /* can't read directory */
         return(func(fullpath, &statbuf, FTW_DNR));
     while ((dirp = readdir(dp)) != NULL) {
         if (strcmp(dirp->d_name, ".") == 0 ||
             strcmp(dirp->d_name, "..") == 0)
                 continue;        /* ignore dot and dot-dot */
         strcpy(ptr, dirp->d_name);   /* append name after slash */
         if ((ret = dopath(func)) != 0)          /* recursive */
              break; /* time to leave */
     }
     ptr[-1] = 0;    /* erase everything from slash onwards */
     if (closedir(dp) < 0)
     {		 
         printf("can't close directory %s", fullpath);
         return -1;
	 }
     return(ret);
}

static int
myfunc(const char *pathname, const struct stat *statptr, int type)
{
    switch (type) {
    case FTW_F:
        switch (statptr->st_mode & S_IFMT) {
        case S_IFREG:    nreg++;    break;
        case S_IFBLK:    nblk++;    break;
        case S_IFCHR:    nchr++;    break;
        case S_IFIFO:    nfifo++;   break;
        case S_IFLNK:    nslink++;  break;
        case S_IFSOCK:   nsock++;   break;
        case S_IFDIR:    printf("for S_IFDIR for %s", pathname); break;
        }
        break;
    case FTW_D:
        ndir++;
        break;
    case FTW_DNR:
        printf("can't read directory %s", pathname);
        break;
    case FTW_NS:
        printf("stat error for %s", pathname);
        break;
    default:
        printf("unknown type %d for pathname %s", type, pathname);
    }
    
    return(0);
}
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 13:39   #6
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
Quote:
Originariamente inviato da sottovento Guarda i messaggi
Puoi usare le primitive contenute in <sys/stat.h>.
Vale a dire, una volta ottenuto il nome del file, ne fai uno stat().

La stat() ti ritornera' le informazioni che ti servono, quali la dimensione del file, se il file e' un regolare/directory/link/... oltre che data di creazione, modifica, ...

Se il file e' regolare, sommi le dimensioni.
Se il file e' directory, la puoi scandire ricorsivamente (e' piu' facile, ma puoi ovviamente fare anche iterativamente)
Codice:
#include <stdio.h> 
#include <dirent.h>
#include <sys/stat.h>

int main (int argc, char **argv)  {  


  DIR *directory;
 struct stat dim;
 struct dirent *dir;
 

 directory=opendir("H:/");


 if(directory!=NULL){
 while((dir= readdir(directory))!=NULL) {

    puts(dir->d_name);

  stat(dir->d_name, &dim);
    printf ("\tDimensione : %f KB\n\n", float(dim.st_size)/1024);
 }
 }
  else{

    perror("Impossibile aprire destinazione!");
  }



 closedir(directory);


 free(dir);

    system ("PAUSE");
    return 0;
}
Ho seguito il tuo consiglio e ho utilizzato stat ma mi da la dimensione dei file sbagliata come mai? se gli do da input il nome preciso del file che mi da la dimensione giusta, se no mi da un numero completamente sballato

Ultima modifica di sam333 : 07-03-2013 alle 13:42.
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 13:40   #7
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Per la dimensione della directory, su Windows, puoi utilizzare diverse api:

http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
Vincenzo1968 non c'è una versione un po più "Sintetica"? o un alternativa?

Ultima modifica di sam333 : 07-03-2013 alle 13:43.
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 14:30   #8
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Si c'è:



Codice:
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>

void getDirInfo(char *dir, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if( (dp = opendir(dir)) == NULL )
    {
        fprintf(stderr, "Impossibile aprire la directory: \"%s\". Addio!\n", dir);
        return;
    }
    
    chdir(dir);
    
    while( (entry = readdir(dp)) != NULL )
    {
        lstat(entry->d_name, &statbuf);
        
        if( S_ISDIR(statbuf.st_mode) )
        {
            /* ignoriamo . and .. */
            if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 )
                continue;
                
            printf("%*s%s/\n", depth, "", entry->d_name);
            
            /* nuovo livello d'indentazione */
            getDirInfo(entry->d_name, depth + 4);
        }
        else
        {
            printf("%*s%s\n", depth, "", entry->d_name);
		}
    }
    
    chdir("..");
    
    closedir(dp);
}

int main(int argc, char* argv[])
{
    char *topdir, pwd[2] = ".";
    
    if (argc != 2)
        topdir = pwd;
    else
        topdir = argv[1];

    printf("Scansione della directory \"%s\"\n", topdir);
    
    getDirInfo(topdir, 0);
    
    printf("Finito!\n");

    return 0;
}

Ultima modifica di Vincenzo1968 : 07-03-2013 alle 14:36.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 15:51   #9
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
grazie mille! mi sono studiato un po il tuo codice e ho due domande :

1) c'è un'alternativa alla libreria "unistd.h"?perchè non è solo per linux?non credo che ci sia su visual c++

2)sai per caso come mai mi da le dimensioni sballate?
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 16:27   #10
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da sam333 Guarda i messaggi
grazie mille! mi sono studiato un po il tuo codice e ho due domande :

1) c'è un'alternativa alla libreria "unistd.h"?perchè non è solo per linux?non credo che ci sia su visual c++

2)sai per caso come mai mi da le dimensioni sballate?
Be careful! Il codice è mio, si, nel senso che l'ho adattato. Ma il codice originale non ricordo più in quale libro/sito l'ho preso. Me lo sono ritrovato nel fottìo di esempi di programmazione che ho accumulato nei vari anni ma purtroppo non ho trovato il riferimento all'articolo/libro/sito originale.

Per quanto riguarda la prima domanda, potresti usare delle librerie che astraggono dal particolare sistrema operativo, tipo QT o Boost. Oppure puoi, più semplicemente, impacchettare le due versioni all'interno di direttive condizionali(#ifdef __linux__, etc).

Per quanto riguarda la domanda 2, no, non lo so. Il consiglio di Sottovento va nella direzione giusta. Non capisco cosa intendi per "se gli do il nome del file preciso". Per forza devi darglielo preciso altrimenti come si fa?

Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 17:04   #11
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Be careful! Il codice è mio, si, nel senso che l'ho adattato. Ma il codice originale non ricordo più in quale libro/sito l'ho preso. Me lo sono ritrovato nel fottìo di esempi di programmazione che ho accumulato nei vari anni ma purtroppo non ho trovato il riferimento all'articolo/libro/sito originale.

Per quanto riguarda la prima domanda, potresti usare delle librerie che astraggono dal particolare sistrema operativo, tipo QT o Boost. Oppure puoi, più semplicemente, impacchettare le due versioni all'interno di direttive condizionali(#ifdef __linux__, etc).

Per quanto riguarda la domanda 2, no, non lo so. Il consiglio di Sottovento va nella direzione giusta. Non capisco cosa intendi per "se gli do il nome del file preciso". Per forza devi darglielo preciso altrimenti come si fa?

se gli do il nome preciso nel senso che gli metto come directory es. "C://text.txt" se invece gli passo d_name mi da una dimensione sballata come vedi nel codice che ho scritto e nn capisco perchè


Comunque o provato a riadattare il codice e come al solito non ci riesco-_-


#ifdef _linux
#include <unistd.h>

#else
#include "stdafx.h"
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>

#endif


non va bene?mi dice #endif imprevisto e che la libreria è stata ignorata

Ultima modifica di sam333 : 07-03-2013 alle 17:21.
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 17:35   #12
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Ecco:



Codice:
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdint.h>

void getDirInfo(char *dir, int depth, uint64_t *pDim)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if( (dp = opendir(dir)) == NULL )
    {
        fprintf(stderr, "Impossibile aprire la directory: \"%s\". Addio!\n", dir);
        return;
    }
    
    chdir(dir);
    
    while( (entry = readdir(dp)) != NULL )
    {
        lstat(entry->d_name, &statbuf);
        
		//*pDim += statbuf.st_size;
                
        if( S_ISDIR(statbuf.st_mode) )
        {			
            /* ignoriamo . and .. */
            if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 )
                continue;
            
			*pDim += statbuf.st_size;                
            printf("%*s%s/\n", depth, "", entry->d_name);
            
            /* nuovo livello d'indentazione */
            getDirInfo(entry->d_name, depth + 4, pDim);
        }
        else
        {
			*pDim += statbuf.st_size;
            printf("%*s%s\n", depth, "", entry->d_name);
		}
    }
    
    chdir("..");
    
    closedir(dp);
}

int main(int argc, char* argv[])
{
	uint64_t dim = 0;
	
    char *topdir, pwd[2] = ".";
    
    if (argc != 2)
        topdir = pwd;
    else
        topdir = argv[1];

    printf("Scansione della directory \"%s\"\n", topdir);
    
    getDirInfo(topdir, 0, &dim);
    
    printf("\nLa dimensione in byte della directory \"%s\" e': %llu\n", topdir, (unsigned long long)dim);

    exit(0);
}

Ultima modifica di Vincenzo1968 : 08-03-2013 alle 17:07.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 17:38   #13
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Se invece vuoi ottenere la dimensione totale, cioè compresa la dimensione di file e directory nascoste, devi fare così:

Codice:
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdint.h>

void getDirInfo(char *dir, int depth, uint64_t *pDim)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if( (dp = opendir(dir)) == NULL )
    {
        fprintf(stderr, "Impossibile aprire la directory: \"%s\". Addio!\n", dir);
        return;
    }
    
    chdir(dir);
    
    while( (entry = readdir(dp)) != NULL )
    {
        lstat(entry->d_name, &statbuf);
        
		*pDim += statbuf.st_size;
                
        if( S_ISDIR(statbuf.st_mode) )
        {			
            /* ignoriamo . and .. */
            if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 )
                continue;
            
			//*pDim += statbuf.st_size;                
            printf("%*s%s/\n", depth, "", entry->d_name);
            
            /* nuovo livello d'indentazione */
            getDirInfo(entry->d_name, depth + 4, pDim);
        }
        else
        {
			//*pDim += statbuf.st_size;
            printf("%*s%s\n", depth, "", entry->d_name);
		}
    }
    
    chdir("..");
    
    closedir(dp);
}

int main(int argc, char* argv[])
{
	uint64_t dim = 0;
	
    char *topdir, pwd[2] = ".";
    
    if (argc != 2)
        topdir = pwd;
    else
        topdir = argv[1];

    printf("Scansione della directory \"%s\"\n", topdir);
    
    getDirInfo(topdir, 0, &dim);
    
    printf("\nLa dimensione in byte della directory \"%s\" e': %llu\n", topdir, (unsigned long long)dim);

    exit(0);
}
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 17:43   #14
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Per le direttive di compilazione condizionale puoi dare un'occhiata alla soluzione postata da AnonimoVeneziano per il punto A del contest 19.

Eccolo:
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

#if _WIN32
#include <Windows.h>
#define RESTRICT __restrict
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
#define fseeko _fseeki64
#define ftello _ftelli64

const char* files_dir = ".\\All\\*";

#else

#include <stdint.h>
#include <stdbool.h>
#include <dirent.h>
#define RESTRICT restrict
#define TRUE true
#define FALSE false
const char* files_dir = "./All/";
#endif

#define DEFAULT_LINE_NUM 100000
#define MB_MULTIPLIER 1024*1024ULL
#define GB_MULTIPLIER 1024*1024*1024ULL
#define IS_SPECIAL_DIRECTORY(x) (x[0] == '.' && \
        			(x[1] == '.' || x[1] == '\0'))

uint8_t file_nums = 0;
size_t text_size = 0;
char* RESTRICT full_text = NULL;
uint32_t lines_num = 0;
int64_t output_size_bytes = 0;
int64_t written_bytes = 0;
char* RESTRICT * RESTRICT lines_ptrs = NULL;
const char* usage_string = "Usage: c19input NameInputFile [-DFileSize]\n\n"
                           "The size of the output file is defined in this way:\n\n"
                           "-D1MB\toutput file is 1MB\n-D1GiB\t output file is 1 GB\n\n"
                           "The maximum file size is 55 GiB";

size_t get_file_size(const char* RESTRICT fname) {
  size_t size;
  FILE* f = fopen(fname, "r");
  fseeko(f, 0L, SEEK_END);
  size = ftello(f);
  fclose(f);
  return size;
}

void read_files(char* RESTRICT * RESTRICT fnames, int fnums) {
  size_t pos_counter = 0;
  size_t* RESTRICT files_size = 
	  (size_t* RESTRICT)malloc(sizeof(size_t)*fnums);

  for (int i = 0; i < fnums; ++i) {
    files_size[i] = get_file_size(fnames[i]);
    text_size += files_size[i];
  }

  full_text = (char * RESTRICT) malloc(sizeof(char)*(text_size+1));

  // Read the entire text of files into the array
  for (int i = 0; i < fnums; ++i) {
    FILE* f = fopen(fnames[i], "r");
    pos_counter += fread(full_text+pos_counter, sizeof(char), files_size[i], f);
    fclose(f);
  }

  full_text[text_size] = '\0';

  free(files_size);
}

#if !_WIN32
bool load_files(const char* directory) {

  DIR* RESTRICT dir_obj = opendir(directory);
  struct dirent* RESTRICT dir_struct;
  char * RESTRICT * RESTRICT files_names;
  const uint16_t path_size = strlen(directory);

  int count = 0;

  if (dir_obj == NULL)
    return TRUE;

  while ((dir_struct = readdir(dir_obj)) != NULL) {
    //printf("File name: %s\n", dir_struct->d_name);
    if (!IS_SPECIAL_DIRECTORY(dir_struct->d_name))
      ++file_nums;
  }

  rewinddir(dir_obj);

  files_names = malloc(file_nums*sizeof(char*));  

  while ((dir_struct = readdir(dir_obj)) != NULL) {
    if (!IS_SPECIAL_DIRECTORY(dir_struct->d_name)) {
      int name_size = strlen(dir_struct->d_name);
      int size = path_size + name_size + 1;
 
      files_names[count] = malloc(sizeof(char)*size);
      strncpy(files_names[count], directory, path_size);
      strncpy(files_names[count]+path_size, dir_struct->d_name, name_size);
      //printf("%s\n", files_names[count]);
      ++count;
    }
  }

  closedir(dir_obj);

  //printf("%d\n", file_nums);
  //printf("Size of dir: %d\n", path_size);
  
  // Read files
  read_files(files_names, file_nums);

  for (int i = 0; i < file_nums; ++i)
    free((void*)files_names[i]);

  free((void**)files_names);
 
  return FALSE;
}
#else

bool load_files(const char* directory) {

  WIN32_FIND_DATA find_data;
  HANDLE hFind;
  char * RESTRICT * RESTRICT files_names;
  const uint16_t path_size = strlen(directory)-1;

  int count = 0;
  hFind = FindFirstFile(directory, &find_data);
  if ( hFind == INVALID_HANDLE_VALUE)
    return TRUE;

  do  {
    //printf("File name: %s\n", dir_struct->d_name);
	if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        ++file_nums;
  } while (FindNextFile(hFind, &find_data));

  FindClose(hFind);
  hFind = FindFirstFile(directory, &find_data);

  files_names = 
	  (char* RESTRICT * RESTRICT) malloc(file_nums*sizeof(char*));  

  do {
    if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      int name_size = strlen(find_data.cFileName);
      int size = path_size + name_size + 1;
      files_names[count] = 
		  (char* RESTRICT)malloc(sizeof(char)*size);
      strncpy(files_names[count], directory, path_size);
	  strncpy(files_names[count]+path_size, find_data.cFileName, name_size+1);
      //printf("%s\n", files_names[count]);
      ++count;
    }
  } while (FindNextFile(hFind, &find_data));

  FindClose(hFind);

  //printf("%d\n", file_nums);
  //printf("Size of dir: %d\n", path_size);
  
  // Read files
  read_files(files_names, file_nums);

  for (int i = 0; i < file_nums; ++i)
    free((void*)files_names[i]);

  free((void**)files_names);
 
  return FALSE;
}

#endif

// Determines the number of lines and normalizes the text
void process_lines() {
  lines_ptrs = 
	(char* RESTRICT * RESTRICT) malloc(sizeof(char*)*DEFAULT_LINE_NUM);
  uint32_t correction = 0;
  uint32_t curr_max_lines = DEFAULT_LINE_NUM;
  lines_ptrs[0] = full_text;
  bool has_character = FALSE;

  for (size_t i = 0; i <= text_size; ++i) {
    switch (full_text[i]) {
      default: {
        full_text[i-correction] = full_text[i];
        has_character = TRUE;
        break;
      }
      case '\t': {
        full_text[i-correction] = ' ';
        break;
      }
      case '\n': {
        if (full_text[i-correction-1] != '\0') {
          if (has_character)
            lines_ptrs[++lines_num] = &full_text[i-correction+1];
          full_text[i-correction] = '\0';
          has_character = FALSE;
        } else
          ++correction;
        break;
      }
      case '\r': {
        if (full_text[i-correction-1] != '\0') {
          if (has_character)
            lines_ptrs[++lines_num] = &full_text[i-correction+1];
          full_text[i-correction] = '\0';
          has_character = FALSE;
        } else
          ++correction;
        break;
      }
      case ' ': {
        if (full_text[i-correction-1] != ' ' && has_character)
          full_text[i-correction] = ' ';
        else
          ++correction;
        break;
      }

    }
    // Expand line buffer
    if (lines_num >= curr_max_lines) {
      curr_max_lines = 2*curr_max_lines;
      char* RESTRICT * RESTRICT new_lines_ptr = 
		  (char* RESTRICT * RESTRICT) malloc(sizeof(char*)*curr_max_lines);
      memcpy((void* RESTRICT)new_lines_ptr, (const void* RESTRICT)lines_ptrs, lines_num);
      free((void*)lines_ptrs);
      lines_ptrs = new_lines_ptr;
    }
  }
}

void shuffle_lines() {
  for (uint32_t i = lines_num-1; i > 0; --i) {
    uint32_t rand_idx = rand() % (i+1);
    char* temp = lines_ptrs[i];
    lines_ptrs[i] = lines_ptrs[rand_idx];
    lines_ptrs[rand_idx] = temp;
  }
}

bool generate_output(FILE* output) {
  for (uint32_t i = 0; i < lines_num && written_bytes < output_size_bytes; ++i) {
    int32_t str_len = strlen(lines_ptrs[i]);
    if (str_len + written_bytes > output_size_bytes)
      str_len = output_size_bytes - written_bytes - 1;
    written_bytes += fwrite(lines_ptrs[i], sizeof(char), str_len, output) + 1;
    fputc('\n', output);
  }

  if (written_bytes >= output_size_bytes)
    return FALSE;
  
  return TRUE;
}

void show_usage() {
  printf("%s\n\n", usage_string);
}

int main(int argc, char **argv) {

  bool error = FALSE;
  FILE* output_file = NULL;

  if (argc == 2) {
    output_size_bytes = 1024*1024ULL;
  } else if (argc == 3) {
    char *arg2 = argv[2];
    uint8_t unit_idx = 0;
    char size[3] = { 0 };
    uint64_t size_num;
    
    if (strncmp(arg2, "-D", 2)) goto parse_error;

    while (*(arg2+2+unit_idx) != '\0' && 
           isdigit(*(arg2+2+unit_idx))) {
      if ( unit_idx >= 3 ) goto parse_error;
      size[unit_idx++] = *(arg2+2+unit_idx);
    }
    size_num = atoi(size);

    if (size_num == 0) goto parse_error;

    if (!strncmp(arg2+2+unit_idx, "GiB", 3))
      size_num = size_num*GB_MULTIPLIER;
    else if (!strncmp(arg2+2+unit_idx, "MB", 2))
      size_num = size_num*MB_MULTIPLIER;
    else goto parse_error;

    output_size_bytes = size_num;
  } else {

parse_error:
    show_usage();
    return 1;
  }

  srand(time(NULL));

  //printf("Started loading the files\n");
  clock_t t = clock();
  error = load_files(files_dir); 
  
  printf("Files loaded, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC);

  if (error) {
    if (full_text)
      free(full_text);
    return 1;
  }

  output_file = fopen(argv[1], "w"); 

  //printf("Started processing the files\n");
  t = clock();
 
  process_lines();
  printf("File processing finished, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC);

  //printf("Started final file output\n");
  t = clock();
 
  do {
    shuffle_lines();
  } while (generate_output(output_file));
  printf("Final file output finished, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC);

  free((void*)full_text);
  free((void*)lines_ptrs);
  fclose(output_file);

  return 0;
}

Ultima modifica di Vincenzo1968 : 07-03-2013 alle 17:45.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 17:50   #15
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Per le direttive di compilazione condizionale puoi dare un'occhiata alla soluzione postata da AnonimoVeneziano per il punto A del contest 19.

Eccolo:
Codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

#if _WIN32
#include <Windows.h>
#define RESTRICT __restrict
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
#define fseeko _fseeki64
#define ftello _ftelli64

const char* files_dir = ".\\All\\*";

#else

#include <stdint.h>
#include <stdbool.h>
#include <dirent.h>
#define RESTRICT restrict
#define TRUE true
#define FALSE false
const char* files_dir = "./All/";
#endif

#define DEFAULT_LINE_NUM 100000
#define MB_MULTIPLIER 1024*1024ULL
#define GB_MULTIPLIER 1024*1024*1024ULL
#define IS_SPECIAL_DIRECTORY(x) (x[0] == '.' && \
        			(x[1] == '.' || x[1] == '\0'))

uint8_t file_nums = 0;
size_t text_size = 0;
char* RESTRICT full_text = NULL;
uint32_t lines_num = 0;
int64_t output_size_bytes = 0;
int64_t written_bytes = 0;
char* RESTRICT * RESTRICT lines_ptrs = NULL;
const char* usage_string = "Usage: c19input NameInputFile [-DFileSize]\n\n"
                           "The size of the output file is defined in this way:\n\n"
                           "-D1MB\toutput file is 1MB\n-D1GiB\t output file is 1 GB\n\n"
                           "The maximum file size is 55 GiB";

size_t get_file_size(const char* RESTRICT fname) {
  size_t size;
  FILE* f = fopen(fname, "r");
  fseeko(f, 0L, SEEK_END);
  size = ftello(f);
  fclose(f);
  return size;
}

void read_files(char* RESTRICT * RESTRICT fnames, int fnums) {
  size_t pos_counter = 0;
  size_t* RESTRICT files_size = 
	  (size_t* RESTRICT)malloc(sizeof(size_t)*fnums);

  for (int i = 0; i < fnums; ++i) {
    files_size[i] = get_file_size(fnames[i]);
    text_size += files_size[i];
  }

  full_text = (char * RESTRICT) malloc(sizeof(char)*(text_size+1));

  // Read the entire text of files into the array
  for (int i = 0; i < fnums; ++i) {
    FILE* f = fopen(fnames[i], "r");
    pos_counter += fread(full_text+pos_counter, sizeof(char), files_size[i], f);
    fclose(f);
  }

  full_text[text_size] = '\0';

  free(files_size);
}

#if !_WIN32
bool load_files(const char* directory) {

  DIR* RESTRICT dir_obj = opendir(directory);
  struct dirent* RESTRICT dir_struct;
  char * RESTRICT * RESTRICT files_names;
  const uint16_t path_size = strlen(directory);

  int count = 0;

  if (dir_obj == NULL)
    return TRUE;

  while ((dir_struct = readdir(dir_obj)) != NULL) {
    //printf("File name: %s\n", dir_struct->d_name);
    if (!IS_SPECIAL_DIRECTORY(dir_struct->d_name))
      ++file_nums;
  }

  rewinddir(dir_obj);

  files_names = malloc(file_nums*sizeof(char*));  

  while ((dir_struct = readdir(dir_obj)) != NULL) {
    if (!IS_SPECIAL_DIRECTORY(dir_struct->d_name)) {
      int name_size = strlen(dir_struct->d_name);
      int size = path_size + name_size + 1;
 
      files_names[count] = malloc(sizeof(char)*size);
      strncpy(files_names[count], directory, path_size);
      strncpy(files_names[count]+path_size, dir_struct->d_name, name_size);
      //printf("%s\n", files_names[count]);
      ++count;
    }
  }

  closedir(dir_obj);

  //printf("%d\n", file_nums);
  //printf("Size of dir: %d\n", path_size);
  
  // Read files
  read_files(files_names, file_nums);

  for (int i = 0; i < file_nums; ++i)
    free((void*)files_names[i]);

  free((void**)files_names);
 
  return FALSE;
}
#else

bool load_files(const char* directory) {

  WIN32_FIND_DATA find_data;
  HANDLE hFind;
  char * RESTRICT * RESTRICT files_names;
  const uint16_t path_size = strlen(directory)-1;

  int count = 0;
  hFind = FindFirstFile(directory, &find_data);
  if ( hFind == INVALID_HANDLE_VALUE)
    return TRUE;

  do  {
    //printf("File name: %s\n", dir_struct->d_name);
	if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        ++file_nums;
  } while (FindNextFile(hFind, &find_data));

  FindClose(hFind);
  hFind = FindFirstFile(directory, &find_data);

  files_names = 
	  (char* RESTRICT * RESTRICT) malloc(file_nums*sizeof(char*));  

  do {
    if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      int name_size = strlen(find_data.cFileName);
      int size = path_size + name_size + 1;
      files_names[count] = 
		  (char* RESTRICT)malloc(sizeof(char)*size);
      strncpy(files_names[count], directory, path_size);
	  strncpy(files_names[count]+path_size, find_data.cFileName, name_size+1);
      //printf("%s\n", files_names[count]);
      ++count;
    }
  } while (FindNextFile(hFind, &find_data));

  FindClose(hFind);

  //printf("%d\n", file_nums);
  //printf("Size of dir: %d\n", path_size);
  
  // Read files
  read_files(files_names, file_nums);

  for (int i = 0; i < file_nums; ++i)
    free((void*)files_names[i]);

  free((void**)files_names);
 
  return FALSE;
}

#endif

// Determines the number of lines and normalizes the text
void process_lines() {
  lines_ptrs = 
	(char* RESTRICT * RESTRICT) malloc(sizeof(char*)*DEFAULT_LINE_NUM);
  uint32_t correction = 0;
  uint32_t curr_max_lines = DEFAULT_LINE_NUM;
  lines_ptrs[0] = full_text;
  bool has_character = FALSE;

  for (size_t i = 0; i <= text_size; ++i) {
    switch (full_text[i]) {
      default: {
        full_text[i-correction] = full_text[i];
        has_character = TRUE;
        break;
      }
      case '\t': {
        full_text[i-correction] = ' ';
        break;
      }
      case '\n': {
        if (full_text[i-correction-1] != '\0') {
          if (has_character)
            lines_ptrs[++lines_num] = &full_text[i-correction+1];
          full_text[i-correction] = '\0';
          has_character = FALSE;
        } else
          ++correction;
        break;
      }
      case '\r': {
        if (full_text[i-correction-1] != '\0') {
          if (has_character)
            lines_ptrs[++lines_num] = &full_text[i-correction+1];
          full_text[i-correction] = '\0';
          has_character = FALSE;
        } else
          ++correction;
        break;
      }
      case ' ': {
        if (full_text[i-correction-1] != ' ' && has_character)
          full_text[i-correction] = ' ';
        else
          ++correction;
        break;
      }

    }
    // Expand line buffer
    if (lines_num >= curr_max_lines) {
      curr_max_lines = 2*curr_max_lines;
      char* RESTRICT * RESTRICT new_lines_ptr = 
		  (char* RESTRICT * RESTRICT) malloc(sizeof(char*)*curr_max_lines);
      memcpy((void* RESTRICT)new_lines_ptr, (const void* RESTRICT)lines_ptrs, lines_num);
      free((void*)lines_ptrs);
      lines_ptrs = new_lines_ptr;
    }
  }
}

void shuffle_lines() {
  for (uint32_t i = lines_num-1; i > 0; --i) {
    uint32_t rand_idx = rand() % (i+1);
    char* temp = lines_ptrs[i];
    lines_ptrs[i] = lines_ptrs[rand_idx];
    lines_ptrs[rand_idx] = temp;
  }
}

bool generate_output(FILE* output) {
  for (uint32_t i = 0; i < lines_num && written_bytes < output_size_bytes; ++i) {
    int32_t str_len = strlen(lines_ptrs[i]);
    if (str_len + written_bytes > output_size_bytes)
      str_len = output_size_bytes - written_bytes - 1;
    written_bytes += fwrite(lines_ptrs[i], sizeof(char), str_len, output) + 1;
    fputc('\n', output);
  }

  if (written_bytes >= output_size_bytes)
    return FALSE;
  
  return TRUE;
}

void show_usage() {
  printf("%s\n\n", usage_string);
}

int main(int argc, char **argv) {

  bool error = FALSE;
  FILE* output_file = NULL;

  if (argc == 2) {
    output_size_bytes = 1024*1024ULL;
  } else if (argc == 3) {
    char *arg2 = argv[2];
    uint8_t unit_idx = 0;
    char size[3] = { 0 };
    uint64_t size_num;
    
    if (strncmp(arg2, "-D", 2)) goto parse_error;

    while (*(arg2+2+unit_idx) != '\0' && 
           isdigit(*(arg2+2+unit_idx))) {
      if ( unit_idx >= 3 ) goto parse_error;
      size[unit_idx++] = *(arg2+2+unit_idx);
    }
    size_num = atoi(size);

    if (size_num == 0) goto parse_error;

    if (!strncmp(arg2+2+unit_idx, "GiB", 3))
      size_num = size_num*GB_MULTIPLIER;
    else if (!strncmp(arg2+2+unit_idx, "MB", 2))
      size_num = size_num*MB_MULTIPLIER;
    else goto parse_error;

    output_size_bytes = size_num;
  } else {

parse_error:
    show_usage();
    return 1;
  }

  srand(time(NULL));

  //printf("Started loading the files\n");
  clock_t t = clock();
  error = load_files(files_dir); 
  
  printf("Files loaded, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC);

  if (error) {
    if (full_text)
      free(full_text);
    return 1;
  }

  output_file = fopen(argv[1], "w"); 

  //printf("Started processing the files\n");
  t = clock();
 
  process_lines();
  printf("File processing finished, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC);

  //printf("Started final file output\n");
  t = clock();
 
  do {
    shuffle_lines();
  } while (generate_output(output_file));
  printf("Final file output finished, it took: %f seconds\n", ((float)(clock() - t)) / CLOCKS_PER_SEC);

  free((void*)full_text);
  free((void*)lines_ptrs);
  fclose(output_file);

  return 0;
}
grazie tante!! sto già iniziando a riscrivere il codice ma posso chiederti un ultima cosa?
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 19:31   #16
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da sam333 Guarda i messaggi
grazie tante!! sto già iniziando a riscrivere il codice ma posso chiederti un ultima cosa?
Che sia l'ultima però eh!


Scheeeeerzo! Chiedi pure
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 19:45   #17
sam333
Member
 
Iscritto dal: Jan 2013
Messaggi: 205
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Che sia l'ultima però eh!


Scheeeeerzo! Chiedi pure
sìsì tranquillo comunque come posso fare per andare nella directory desktop per esempio senza sapere il nome utente?O.o come implemento il codice?
sam333 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 22:38   #18
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515



ScanDir.h:
Codice:
#ifndef _MY_SCANDIR_
#define _MY_SCANDIR_

// Dati usati dalla funzione DirWalkRecurse
typedef struct
{
	TCHAR  szInitPath[_MAX_DIR];		// Path iniziale
	TCHAR  szCurrPath[_MAX_DIR];		// Path corrente
	TCHAR  szPathParent[_MAX_DIR];		// Path genitore di szCurrPath
	TCHAR  szCurrDir[_MAX_DIR];			// Path temporaneo; ci servirà per la ricerca dei files
	int    nDepth;						// Profondità
	BOOL   fRecurse;					// impostare a TRUE per ottenere la scansione delle sottodirectory. 
	TCHAR  szBuf[1024];					// Buffer per l'output formattato 
	int    nIndent;						// Contatore per l'indentazione 
	BOOL   fOk;							// Loop control flag 
	BOOL   fIsDir;						// Loop control flag 
	WIN32_FIND_DATA FindData;			// Informazioni sui file 
} DIRWALKDATA, *LPDIRWALKDATA;

void getDirInfo(LPCTSTR pszRootPath, BOOL fRecurse, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA));

#endif
ScanDir.c:
Codice:
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0]))

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#include "ScanDir.h"

BOOL IsChildDir (WIN32_FIND_DATA *lpFindData)
{
	return
		(
			(lpFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
			(lpFindData->cFileName[0] != __TEXT('.'))
		);
}

BOOL FindNextChildDir (HANDLE hFindFile, WIN32_FIND_DATA *lpFindData)
{
	BOOL fFound = FALSE;
	do
	{
		fFound = FindNextFile(hFindFile, lpFindData);
	} while (fFound && !IsChildDir(lpFindData));
	
	return(fFound);
}

HANDLE FindFirstChildDir (LPTSTR szPath, WIN32_FIND_DATA *lpFindData)
{
	BOOL fFound;
	HANDLE hFindFile = FindFirstFile(szPath, lpFindData);

	if (hFindFile != INVALID_HANDLE_VALUE)
	{
		fFound = IsChildDir(lpFindData);
		if (!fFound)
			fFound = FindNextChildDir(hFindFile, lpFindData);
		
		if (!fFound)
		{
			FindClose(hFindFile);
			hFindFile = INVALID_HANDLE_VALUE;
		}
	}
	
	return(hFindFile);
}

void GetParentDirectory(LPCTSTR szPath, LPTSTR szParent)
{
	size_t nLen;
	nLen = _tcslen(szPath);

	_tcscpy(szParent, szPath);


	if ( szPath[0] == '\\' )
		return;

	while ( nLen > 0 )
	{
		if ( *(szParent + nLen-1) == '\\' )
		{
			*(szParent + nLen-1) = '\0';
			break;
		}

		--nLen;
	}
}

// Percorre la struttura della directory.
// Se il campo pDW->fRecurse è TRUE, percorre ricorsivamente anche le sottodirectory.m
void DirWalkRecurse (LPDIRWALKDATA pDW, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA))
{
	HANDLE hFind;
	pDW->szCurrDir[0] = '\0';
	
	pDW->nDepth++;
	
	pDW->nIndent = 3 * pDW->nDepth;
	_stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent, __TEXT(""));

	
	// Imposta il buffer alla directory iniziale e chiama la funzione evento
	// fornita dall'utente.
	_tcscpy(&pDW->szBuf[pDW->nIndent], pDW->szCurrPath);

	if ( pfnOnChange )
		(*pfnOnChange)(pDW);
	//printf("pDW->szBuf -----> %s\n", pDW->szBuf);


	// Inizia a leggere il contenuto della directory iniziale
	_tcscpy(pDW->szCurrDir, pDW->szCurrPath);
	_tcscat(pDW->szCurrDir, __TEXT("\\*.*"));

	hFind = FindFirstFile( pDW->szCurrDir, &pDW->FindData);
	pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
	
	while (pDW->fOk)
	{
		pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
		if ( !pDW->fIsDir || (!pDW->fRecurse && IsChildDir(&pDW->FindData)) )
		{
			_stprintf(
				pDW->szBuf,
				pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"),
				pDW->nIndent, __TEXT(""),
				pDW->FindData.cFileName);
				
			*pDim += (pDW->FindData.nFileSizeHigh * (MAXDWORD+1)) + pDW->FindData.nFileSizeLow;

			// Per ogni file ( o sottodirectory ) trovato,
			// chiamiamo la funzione fornita dall'utente
			// passandogli i dati relativi tramite il puntatore alla struct pDW.
			if ( pfnOnChange )
				(*pfnOnChange)(pDW);
			//printf("pDW->szBuf -----> %s\n", pDW->szBuf);

		}
		pDW->fOk = FindNextFile(hFind, &pDW->FindData);
	}
	if (hFind != INVALID_HANDLE_VALUE)
		FindClose(hFind);
	
	// se fRecurse è TRUE, leggiamo ricorsivamente le sottodirectory
	if (pDW->fRecurse)
	{
		// Ottiene la prima directory figlia
		hFind = FindFirstChildDir( pDW->szCurrDir, &pDW->FindData );
		pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
		while (pDW->fOk)
		{
			// Passa alla directory figlia
			_tcscat(pDW->szCurrPath, __TEXT("\\"));
			_tcscat(pDW->szCurrPath, pDW->FindData.cFileName);

			DirWalkRecurse(pDW, pDim, pfnOnChange);

			// Ritorna alla directory genitore
			GetParentDirectory(pDW->szCurrPath, pDW->szPathParent);
			_tcscpy(pDW->szCurrPath, pDW->szPathParent);

			pDW->fOk = FindNextChildDir(hFind, &pDW->FindData);
		}
		
		if (hFind != INVALID_HANDLE_VALUE)
			FindClose(hFind);
	}
	pDW->nDepth--;
}

// Funzioni esportate
/////////////////////////////////////////////////////////////

// Il parametro pszRootPath è il percorso completo della directory da esaminare
// Il parametro fRecurse è un valore booleano che indica
// se vogliamo leggere anche le sottodirectory. Se impostato a FALSE, la funzione
// legge solo la directory passata nel parametro pszRootPath
// Il parametro pfnOnChange è un puntatore a una funzione evento che deve essere
// implementata dal client ( il programma che utilizza la DLL )

void getDirInfo(LPCTSTR pszRootPath, BOOL fRecurse, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA))
{
	DIRWALKDATA DW;
	
	DW.szBuf[0] = '\0';
	DW.szCurrDir[0] = '\0';
	DW.szCurrPath[0] = '\0';
	DW.szInitPath[0] = '\0';
	DW.szPathParent[0] = '\0';

	// nDepth è usato per controllare l'indentazione. Il valore -1
	// fa si che il primo livello sia visualizzato allineato a sinistra
	DW.nDepth = -1;

	DW.fRecurse = fRecurse;

	_tcscpy(DW.szInitPath, pszRootPath);
	_tcscpy(DW.szCurrPath, pszRootPath);

	// Leggiamo il contenuto della directory passata nel parametro pszRootPath.
	// Se il parametro fRecurse è TRUE, leggiamo anche le sottodirectory
	DirWalkRecurse(&DW, pDim, pfnOnChange);
}
ScanDirClient.c:
Codice:
#include <windows.h>

#include <stdio.h>
#include <stdint.h>
#include "scandir.h"

void CALLBACK OnChange(LPDIRWALKDATA pDW)
{
	printf("# -> %s\n", pDW->szBuf);
}

int main(int argc, char* argv[])
{
	uint64_t dim = 0;
	
	if( argc < 2 )
		return -1;

	getDirInfo(argv[1], TRUE, &dim, OnChange);
	
	printf("\nLa dimensione della directory \"%s\" e': %llu byte\n", argv[1], (unsigned long long)dim);

	return 0;
}

Ultima modifica di Vincenzo1968 : 07-03-2013 alle 22:43.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 07-03-2013, 22:39   #19
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da sam333 Guarda i messaggi
sìsì tranquillo comunque come posso fare per andare nella directory desktop per esempio senza sapere il nome utente?O.o come implemento il codice?
Boh!
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 08-03-2013, 07:29   #20
The_ouroboros
Senior Member
 
L'Avatar di The_ouroboros
 
Iscritto dal: May 2007
Città: Milano
Messaggi: 7103
Quote:
Originariamente inviato da sam333 Guarda i messaggi
comunque come posso fare per andare nella directory desktop per esempio senza sapere il nome utente?O.o
La vedo dura


Inviato dal mio Sony Xperia P
__________________
Apple Watch Ultra + iPhone 15 Pro Max + Rog Ally + Legion Go
The_ouroboros è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Borderlands 4, tra divertimento e problemi tecnici Recensione Borderlands 4, tra divertimento e pro...
TCL NXTPAPER 60 Ultra: lo smartphone che trasforma la lettura da digitale a naturale TCL NXTPAPER 60 Ultra: lo smartphone che trasfor...
Un fulmine sulla scrivania, Corsair Sabre v2 Pro ridefinisce la velocità nel gaming Un fulmine sulla scrivania, Corsair Sabre v2 Pro...
Nokia Innovation Day 2025: l’Europa ha bisogno di campioni nelle telecomunicazioni Nokia Innovation Day 2025: l’Europa ha bisogno d...
Sottile, leggero e dall'autonomia WOW: OPPO Reno14 F conquista con stile e sostanza Sottile, leggero e dall'autonomia WOW: OPPO Reno...
iPhone 17 Pro, esplode lo Scratchgate: A...
Amazon mette il turbo agli sconti: 31 of...
Meta domina i social: anche Instagram ra...
Il processore di ritorno al futuro: a 5 ...
Call of Duty: Black Ops 7 Zombi, tutte l...
Intel, in arrivo un aumento dei prezzi s...
Il passaggio al 6G è vicino: Qual...
Amazon abbassa i prezzi: da Lenovo a HP,...
NBA su Prime Video: la squadra di commen...
Supermicro: server con vulnerabilit&agra...
Dreame X40 Master: il robot aspirapolver...
Lo smartphone si può usare solo p...
Microsoft aggiunge i modelli Claude di A...
iPhone 16e all'incredibile prezzo di 499...
OpenAI - NVIDIA, tra investimenti e GPU ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 09:28.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v