I'm using dirent.h to loop inside dir recursivly.
I want to edit the name of a file then past his data and his new name to a new file.
Here i can loop and edit his name with a new extension (.enc), the only problem is that weird symbol appear between my PATH and my D_NAME (aka "fn" after edit).
Here is my code and an exemple.
while(1)
{
struct dirent *entry;
const char *d_name;
unsigned char d_type;
entry = readdir(d);
if(!entry)
{
// no more entries in this directory -> break the loop
break;
}
d_name = entry->d_name;
d_type = entry->d_type;
if(strcmp(d_name, ".")!=0)
{
if(strcmp(d_name, "..")!=0)
{
if(d_type == DT_REG)
{
if(de_flag=='e')
{
char *fn = NULL;
fn = malloc(400*sizeof(char));
strcat(fn, d_name);
strcat(fn, ".enc");
char abs1_path[PATH_MAX];
snprintf(abs1_path, PATH_MAX, "%s/%s", name, fn);
char ch;
char abs_path[PATH_MAX];
snprintf(abs_path, PATH_MAX, "%s/%s", name, d_name);
printf("%s %s\n", abs1_path, abs_path);
FILE *source, *target;
//source = fopen(abs_path, "r");
//target = fopen(abs1_path, "w");
As u can see, on the first lap of the loop, there is no problem on the new filename
So i think the problem comes from the malloc() or something like this. (i use free(fn)) after, but dont wanted to show ALL the source code.
Related
Is there a way where you can update the char arrays of a base path with an updated path?
struct dirent *dp;
DIR *dir;
struct stat buf;
dir = opendir("./statdir/");
int x;
char base_path[11] = "./statdir/";
char* full_path;
int main(int argc, char* argv[]){
while((dp = readdir(dir)) != NULL) {
full_path = strcat(base_path, dp->d_name);
if((x = lstat(full_path, &buf)) == -1) {
perror("stat failed");
exit(1);
}
printf("Debug: %s\n", full_path);
}
closedir(dir);
return(0);
}
}
My goal is to update full_path after each loop to the base_path + whatever argument is passed to argv[] and in my directory i have two files name file1 and file2....
i.e if I ran my code and wrote ./Stat, I expected full_path to be "./statdir/file1" and then "./statdir/file2"
The results I am getting however is :
Debug: ./statdir/.
Debug: ./statdir/...
stat failed: No such file or directory
You could build the full filename using snprintf like this...
snprintf(full_path, PATH_MAX, "%s/%s",base_path, dp->d_name);
...but you'll first need to ensure that full_path has the space to contain the filename so replace
char *full_path;
with
char full_path[PATH_MAX];
You're concatenating a string onto base_path, however that array is just long enough for what you initialized with. That means you're writing past the end of the array. This invokes undefined behavior.
Also note that full_path is pointing to the start of base_path.
Instead, make full_path an array big enough to hold a full path. Then use strcpy to copy over the base path, then strcat to add on the current entry.
char full_path[100];
...
while((dp = readdir(dir)) != NULL) {
strcpy(full_path, base_path);
strcat(full_path, dp->d_name);
In my program stat is only working for a current directory. Can any one please help me with this.
even though I am passing parameter from main it is only working for current directory.
and source path is good it is printing correct path which I have passed from the main.
DIR *dr;
struct dirent *cur;
struct stat fi;
long int total_size = 0;
dr = opendir(source);
char *name;
printf("%s\n\n\n", source);
if (!(dr))
{
perror("opendir()");
return(1);
}
while (cur = readdir(dr))
{
if(cur->d_name[0] != '.')
{
if(stat(cur->d_name, &fi) == -1)
{
printf("error \n\n");
}
else
{
printf("%s ",cur->d_name);
printf("%ld ",fi.st_blocks);
total_size = total_size + fi.st_blocks;
}
}
}
printf("\n\ntotal_size = %ld \n", total_size);
printf("\n\n\n");
return 0;
}
cur->d_name only contains the file name.
to get a 'stat()' outside the current directory,
need to prefix with the path string.
Also need to check if the returned struct from readdir()
is a file or a sub directory.
The main problem is that stat expects a file path but d_name is just the file name. You can find a working example of how to use stat with d_name here
I'm writing a code where I can be given a directory of .txt files, and specific strings that appear throughout each file, and do some simple comparisons. code chunk will be posted below.
So, My task:Open directory>open file>compare strings>open next file(repeat)
Until I run out of files.
What is wrong:My code currently prints the first file name( full path name) infinitely until it crashes, nothing is printed to fp1. It is supposed to only print the file name once, but it never gets past that first file, where, obviously, I would like it to go through all the files in the directory.
I'm sorry that I'm fairly new to C so I might be unclear as to how these functions actually operate.
Please correct me if I'm wrong, I want to see if I understand correctly.
while ((in_file = readdir(FD))!= NULL){
Should basically traverse through a directory and "look" the name of each file.
I then do some very inefficient work around, which you will probably laugh at me for, and I manage to get the full path name of the first file in the directory.
I then assign that path name to entry_file pointer, where it gets opened by fgets().
I believe fgets() should read each line individually until it sees a EOF character
Now, I had this section working before I added the directory stuff, where I was just opening one file by using fopen() with its full path name, and I haven't touched it. So I don't think my problem is here, but nothing is being printed to fp1 at all, so I really don't know.
I then do some simple string comparisons and try to print matches to fp1
When it reaches the end of the file, it should close the file, and then go back up to readdir() and repeat the process with the next file
Thank you so much for any help. I probably sound like an idiot, but I just have no idea what could cause this.
Yes, I realize its very messy, and I have many unused and pointless variables. I've been trying to figure this out for days, trying many different methods.
int main(void)
{
char str1[10000];
char str2[] = { "Measure L1 current Tank Heater ON: Passed" };
char str3[] = { "Measure L1 current Tank Heater ON: Failed" };
char str4[] = { "Measure L1 current Manifold Heater ON: Passed" };
char str5[] = { "Measure L1 current Manifold Heater ON: Failed" };
char str6[] = { "Measure L1 current (verify heaters off) Manifold: Passed" };
char str7[] = { "Measure L1 current (verify heaters off) Manifold: Failed" };
char sn[] = { "Serial Number: 1" };
DIR* FD;
struct dirent* in_file;
int lcount = 0;//line counter
char *ret;
int linenum = 0;//temp line count
char mes[500];//measurement
double val = 0;//value
char unit[500];//units
char pathstr1[38] = ("C:/Users/liam.king/Desktop/TestFiles/");
char pathstr2[200];
DWORD retval = 0;
char buffer[BUFSIZE] = ("");
char buf[BUFSIZE] = ("");
char** lppPart = {NULL};
FILE *fp, *fp1, *filewrite;
FILE *entry_file;
//fp = fopen("C:/Users/liam.king/Desktop/TestFiles/ProBlueUnit_UpgradeRev4_Report[1022230.SA15E14082][9 39 00 AM][5 19 2015].txt", "r");
fp1 = fopen("C:/Users/liam.king/Desktop/ProBlueTestWrite.txt", "a");
filewrite = fopen("C:/Users/liam.king/Desktop/FileWrite.txt", "w+");
if (fp1 == NULL){
printf("Invalid file name");
return 0;
}
if ((FD = opendir(LONG_DIR_NAME))==NULL)
{
printf("Error: Failed to open directory\n");
return 0;
}
else{
printf("Directory opened successful\n");
}
while ((in_file = readdir(FD))!= NULL){
if (strcmp(in_file->d_name, ".") == 0 || strcmp(in_file->d_name, "..") == 0)
continue;
fprintf(filewrite, "%s", pathstr1);
fprintf(filewrite,"%s", in_file->d_name);
fclose(filewrite);
filewrite = fopen("C:/Users/liam.king/Desktop/FileWrite.txt", "r");
fscanf(filewrite, "%[^\n]%*c", pathstr2);
printf("%s\n", pathstr2);//check file name is correct
entry_file = fopen(pathstr2, "r");
fclose(filewrite);
if (entry_file != NULL){
//printf("SUCCESSFULL OPENING\n");
//fprintf(fp1, "Does this work?\n");
}
else if (entry_file == NULL){
printf("Error: Failed to open entry file\n");
return 0;
}
while (fgets(buffer, 256, entry_file) != NULL){//string being stored in str1 from file *entry_file
lcount++;
ret = strstr(str1, sn);
if (ret != NULL){
fprintf(fp1, "%s\n", str1);
}
ret = strstr(str1, str2);
if (ret != NULL){// compares str1 and 2
fprintf(fp1, "Found"" %s ""at line %d\n", str1, lcount);//if same, declare match and what line found at.
linenum = lcount;
}
//comparing more strings
}
fclose(entry_file);
}
fclose(fp1);
return 0;
}
Since pathstr2 is declared as a local array, you should use this:
while ((in_file = readdir(FD)) != NULL) {
if (!strcmp(in_file->d_name, ".") || !strcmp(in_file->d_name, ".."))
continue;
snprintf(pathstr2, sizeof(pathstr2), "%s%s", pathstr1, in_file->d_name);
entry_file = fopen(pathstr2, "r");
...
while (fgets(buffer, sizeof(buffer), entry_file) != NULL) {
lcount++;
if (strstr(buffer, sn)) {
fprintf(fp1, "%s", buffer);
}
if (strstr(buffer, str1)) {
fprintf(fp1, "Found \"%s\" at line %d\n", str1, lcount);
linenum = lcount;
}
...
}
fclose(entry_file);
}
The tests you perform with strstr on the lines read from entry_file are not incorrect. You should specify buffer instead of str1 as the first argument.
Also note that strstr searches for the second string in the whole line. If the string should be starting at the beginning of the line, you should write:
if (!strncmp(buffer, str1, strlen(str1))) {
// line starts with str1
}
I am trying to create a function that will take an inputted directory path (filrOrDir) and output info for each file in the directory: file name, size, and last access date. The program compiles and prints everything. It prints the right file names but, for each file, the size and last access date are wrong. I thought maybe it was because of my variable declarations being in the while loop but I moved them around and still go the same results. Can somebody please give me a hint or a tip on what I am doing wrong? Below is my code:
void dirInfo(char *fileOrDir)
{
DIR *d;
struct dirent *dir;
d = opendir(fileOrDir);
while((dir = readdir(d)) !=NULL)
{
struct stat *buffer = (struct stat *)malloc(sizeof(struct stat));
char accessString[256];
char *name = (char *)malloc(sizeof(char));
struct tm *tmAccess;
int size = 0;
name = dir->d_name;
stat(name, buffer);
printf("%s ", name);
size = buffer->st_size;
printf("%d bytes ", size);
tmAccess = localtime(&buffer->st_atime);
strftime(accessString, sizeof(accessString), "%a %B %d %H:%M:%S %Y", tmAccess);
printf("%s\n", accessString);
printf("\n");
free(buffer);
}
closedir(d);
}
name = dir->d_name is the name of the file inside the directory fileOrDir, but
stat(name, buffer);
tries to stat the file name in the current working directory.
That fails (unless fileOrDir happens to be the current working directory),
and therefore the contents of buffer is undetermined.
You have to concatenate the directory and the file name for the stat call.
You should also check the return value of the stat call.
For example:
char fullpath[MAXPATHLEN];
snprintf(fullpath, sizeof(fullpath), "%s/%s", fileOrDir, name);
if (stat(fullpath, buffer) == -1) {
printf(stderr, "stat failed: %s\n", strerror(errno));
} else {
// print access time etc.
}
im looking for a code who will recursively list all directories and files of a directory given on argument in C programming, ive find an interresting code (below) but I dont understand the snprintf function and particulary the "/",
I would prefer to use strcat or other system function to override the sprintf function but I dont see how since I dont understand what the snprintf do here.
Heres the code:
int is_directory_we_want_to_list(const char *parent, char *name) {
struct stat st_buf;
if (!strcmp(".", name) || !strcmp("..", name))
return 0;
char *path = alloca(strlen(name) + strlen(parent) + 2);
sprintf(path, "%s/%s", parent, name);
stat(path, &st_buf);
return S_ISDIR(st_buf.st_mode);
}
int list(const char *name) {
DIR *dir = opendir(name);
struct dirent *ent;
while (ent = readdir(dir)) {
char *entry_name = ent->d_name;
printf("%s\n", entry_name);
if (is_directory_we_want_to_list(name, entry_name)) {
// You can consider using alloca instead.
char *next = malloc(strlen(name) + strlen(entry_name) + 2);
sprintf(next, "%s/%s", name, entry_name);
list(next);
free(next);
}
}
closedir(dir);
}
from How to recursively list directories in C on LINUX
Okay, my program is running but now i want to save all the file and directory printed to a file like i run my program ./a.out . > buffer where buffer contain what the program should print on the shell
the line
sprintf(next, "%s/%s", name, entry_name);
could be replaced with
strcpy (next, name);
strcat (next, "/");
strcat (next, entry_name);
and it would do the same thing. Does that clarify it for you?