I have a probleme with a program.
I need to take file name in a folder and put it in a variable.
I tried that:
#define _POSIX_SOURCE
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#undef _POSIX_SOURCE
#include <stdio.h>
int main()
{
DIR *dir;
struct dirent *file;
char fileName;
dir = opendir("../../incoming");
while ((file = readdir(dir)) != NULL)
printf(" %s\n", file->d_name);
fileName = file->d_name;
printf(fileName);
closedir(dir);
return 0;
}
thx
Not very clear what you wanted, I prefer to think you want read the file name into your varible 'fileName' and then handle that varible...
Correct 2 parts:
fileName type should be same as the struct member for assign.
the while loop......
int main(){
DIR *dir;
struct dirent *file;
char fileName[255];
dir = opendir("../../incoming");
while ((file = readdir(dir)) != NULL)
{
printf(" %s\n", file->d_name);
strncpy(fileName, file->d_name, 254);
fileName[254] = '\0';
printf("%s\n", fileName);
}
closedir(dir);
return 0;
}
You need to declare a character array of sufficient size and copy the contents of the file->d_name into it if you want to save it past the call to closedir().
If you want to simply print the name,
printf("%s\n", file->d_name);
would accomplish that.
Related
I am trying to create a C program that will take a directory name as input in main and pass that open directory to the function. I have both components working seperately but cannot figure out how to pass the open directory to the function.Also I am struggling to find the oldest file.
Any help would be appreciated.
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char* argv[]) {
DIR *d;
struct dirent *dir;
if(argc==2){
char* path = argv[1];
d = opendir(path);
if (d) {
while ((dir = readdir(d)) != NULL) {
printf("%s\n", dir->d_name);
}
closedir(d);
}
return(0);
}else{
printf("Wrong number of arguments");
return 1;
}
}
void getFileCreationTime(char *path) {
struct stat attr;
stat(path, &attr);
printf("Last modified time: %s", ctime(&attr.st_mtime));
}
int recent(DIR *d, char *file_name, char *dir_name)
{
struct dirent *entry;
int files = 0;
while( (entry=readdir(entry)) )
{
files++;
printf("File %3d: %s\n",files, entry->d_name);
printf("File %3d: %i\n",files, entry->d_reclen);
getFileCreationTime(".");
}
closedir(entry);
return(0);
}
I believe your issue is in the recent function where you are referencing the incorrect variable (entry instead of d). Following is a snippet of code with a revision of the variable entry.
int recent(DIR *d, char *file_name, char *dir_name)
{
struct dirent *entry;
int files = 0;
while( (entry=readdir(d)) ) /* Revised this line to utilize "d" */
{
files++;
printf("File %3d: %s\n",files, entry->d_name);
printf("File %3d: %i\n",files, entry->d_reclen);
getFileCreationTime(".");
}
closedir(d); /* Revised this line to utilize "d" */
return(0);
}
When I ran the code with this revision, I received the following terminal output.
#Dev:~/C_Programs/Console/Directory/bin/Release$ ./Directory /home/craig/C_Programs/Console/Directory
main.c
bin
obj
..
.
Directory.cbp
Give that a try and see if it meets the spirit of your project.
i am trying to do a program that check a directory and tell me how many txt already exist so i can write a new one sequentially.
What is the best way to do that, and how i do that?
Sorry for my poor english
You can use the dirent header to accomplish this task.
you should iterate through every file in the folder, and then you should just do string manipulation, to get the extension of each file.
#include <stdio.h>
#include <dirent.h>
#include <string.h>
int main()
{
const char *dir = ".";//current dir
printf("opening folder\n");
DIR *root_folder = opendir(dir);
if(root_folder == 0) {
printf("Error opening file");
return -1;
}
struct dirent *file;
while((file = readdir(root_folder)) != NULL) {
if(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
continue;
printf("%s\n", file->d_name);
//you can work with the names here
}
}
As Barmar suggested, you can use the functions opendir() to open the desired directory and readdir() to read its content. readdir() returns a pointer to a dirent struct. More about the struct here. You can later use strrchr() to find the last occurence of . and strcmp() to see if you have a match.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main(void)
{
int txt_count = 0;
DIR *pdir = NULL;
struct dirent *dp = NULL;
char *dir = "."; /* current directory, modify to match your dir */
char *type = NULL;
pdir = opendir(dir); /* opens directory dir */
if (!pdir) /* check if failed to open */
{
fprintf(stderr, "Can't open dir <%s>\n", dir);
exit(EXIT_FAILURE);
}
while ((dp = readdir(pdir))) /* reading contents until NULL */
{
type = strrchr(dp->d_name, '.'); /* get a pointer to the last occurence of '.' in filename */
if (type != NULL && !strcmp(type, ".txt")) /* compare with ".txt",check type for NULL if not found */
{
txt_count++;
}
}
printf("Total txt files in directory </%s> --> %d\n", dir, txt_count);
return 0;
}
I am trying to concatenate two string to use in for a stat function, but when I strcat the char* and then print it shows over two lines like so.
./
boot
tmp
./
tmp
lib
./
lib
lost+found
./
lost+found
sbin
./
sbin
etc
I have tried a few things but i am probably going about this all wrong. Here is my code.
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>
int printDetails(char *path, char *name){
struct stat fileInfo;
char file[100];
strcpy(file, path);
strcat(file, name);
printf("%s\n", file);
return 1;
}
int main(int argc, char *argv[]) {
struct dirent *direntp;
DIR *dirp;
printf("Please Enter directory path\n");
char data[64];
if (fgets(data, sizeof data, stdin)) {
if ((dirp = opendir("/")) == NULL) {
perror ("Failed to open directory");
return 1;
}
while ((direntp = readdir(dirp)) != NULL)
{
printf("%s\n", direntp->d_name);
if(direntp->d_name != "." && direntp->d_name != ".."){
printDetails(data, direntp->d_name);
}
}
while ((closedir(dirp) == -1) && (errno == EINTR)) ;
}
return 0;
}
Any help on this issue would be great.
Thanks very much
fgets will include the \n character at the end of each line. That is, assuming the line of text isn't longer than the size you pass in - otherwise you'll get only part of the line.
I have to store the bmp filename in an array.
eg: files in the current directory
a.bmp b.bmp c.txt d.bmp xyz.exe ...
Currently my output is:
fname[0]=.
fname[1]=..
fname[2]=a.bmp
fname[3]=b.bmp
fname[4]=c.txt
fname[5]=d.bmp
fname[6]=xyz.exe
desired output:
fname[0]=a.bmp
fname[1]=b.bmp
fname[2]=d.bmp
Here is my code.
#include <stdio.h>
#include <dirent.h>
#include <string.h>
int main(int argc, char **argv)
{
char filename[20][256];
DIR *dir;
int i=0,k;
struct dirent *ent;
dir = opendir ("D:\\font\\");
if (dir != NULL)
{
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL)
{
strcpy(filename[i],ent->d_name);
i++;
/* save filenames in the array */
}
closedir (dir);
}
for (k=0;k<i;k++)
printf("%s\t %d\n",filename[k],k);
FILE *fp;
if(!(fp=fopen(filename[i],"rb")))
{
//file handling
}
fclose(fp);
return 0;
}
However, this code save all the files of current directory in the array. Could someone help me out how to store only bmp filename in the array?
try using strstr function; here is a reference for it.
char* str2 = ".bmp";
strstr(filename[i],str2);
This will return NULL for all filenames you don't care about.
This will work only if the file names are in the form of *.* .
You have to check ent->d_name before adding to your array. You can do in your while loop using strrchr and strcmp for example
char *pdot = strrchr(ent->d_name, '.');
if (dot && !strcmp(pdot, ".bmp")) {
strcpy(filename[i], ent->d_name);
i++;
}
Also if you need case case-insensitive string comparisons use strcasecmp instead of strcmp
You're accessing filename[i] at a position, where you haven't copied anything at position i (fopen line, but increased recently at the strcpy line). Be carefull (I commented the affected code out).
To compare the sufix of your c-strings you could use strcmpi() if available (it's not part of ISO-C), but because you're using dirent already which is not part of ISO-C also (but in the POSIX) you probably want to use strcasecmp().
#include <stdio.h>
#include <dirent.h>
#include <string.h>
int main(int argc, char **argv){
char filename[20][256];
DIR *dir;
int i=0,k;
struct dirent *ent;
dir = opendir ("D:\\font\\");
if (dir != NULL){
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL){
size_t offset = strlen(ent->d_name)-4;
if((strlen(ent->d_name) >= 4) && (!strcasecmp(ent->d_name[offset], ".bmp"))){
strcpy(filename[i],ent->d_name);
i++;
/* save filenames in the array */
}
}
closedir (dir);
}
for (k = 0; k < i; k++) {
printf("%s\t %d\n",filename[k],k);
}
/*FILE *fp;
if(!(fp=fopen(filename[i],"rb"))){
//file handling
}
fclose(fp);*/
return 0;
}
Is there a way that I can write a C function that gives me the file size for each file in a directory tree? (similar to the output of du -a)?
I don't have trouble getting any one of the file sizes, but I run into trouble recursing through directories within the main directory.
Is there a way that I can write a C function that gives me the file size for each file in a directory tree?
Yes, there is. You can use the <dirent.h> API to traverse a directory:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <dirent.h>
#include <sys/stat.h>
void recursive_dump(DIR *dir, const char *base)
{
struct dirent *ent;
for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
if (ent->d_name[0] == '.') {
continue;
}
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "%s/%s", base, ent->d_name);
struct stat st;
stat(fname, &st);
if (S_ISREG(st.st_mode)) {
printf("Size of %s is %llu\n", fname, st.st_size);
} else {
DIR *ch = opendir(fname);
if (ch != NULL) {
recursive_dump(ch, fname);
closedir(ch);
}
}
}
}
int main(int argc, char *argv[])
{
DIR *dir = opendir(argv[1]);
recursive_dump(dir, argv[1]);
closedir(dir);
return 0;
}
Yes. You need to use opendir and stat. See 'man 3 opendir', and 'man 2 stat'.
In a nutshell:
#include <dirent.h>
#include <sys/stat.h>
// etc...
void the_du_c_function() {
struct dirent direntBuf;
struct dirent* dirEntry = 0;
const char* theDir = ".";
DIR* dir = opendir(theDir);
while (readdir_r(dir,&direntBuf,dirEntry) && dirEntry) {
struct stat filestat;
char filename[1024];
snprintf(filename,sizeof(filename),"%s/%s",theDir,dirEntry.d_name);
stat(filename,&filestat);
fprintf(stdout,"%s - %u bytes\n",filename,filestat.st_size);
}
}
I just typed that code segment. I did not compile it, but that's the gist of it.