Reputation: 33
What I am trying is to get all the file present in a directory and then add a .enc extension to this file. Example- Let File.txt is present then I will perform some encryption related task and after that the new file name would be File.txt.enc
Here is my code:
#include <dirent.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
DIR *d;
struct dirent *dir;
char *name;
int val;
d = opendir(".");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
name=dir->d_name;
printf("File Found:%s\n",name);
strcat(name,".enc");
val=rename(dir->d_name,name);
if(val==0)
printf("Encrypted File:%s\n",name);
else
perror("Error: ");
}
closedir(d);
}
return(0);
}
But I am getting a output like this......
File Found:write_pgm_img.c
Error: : No such file or directory
File Found:realloc.c
Error: : No such file or directory
File Found:getusage.txt
Error: : No such file or directory
File Found:directory.c
Error: : No such file or directory
As you can see "No such file or directory" error. But I can't understand why?? Please explain.Thanks in advance.
Upvotes: 0
Views: 377
Reputation: 12404
You are messing up pointers and memory content:
name=dir->d_name;
printf("File Found:%s\n",name);
strcat(name,".enc");
val=rename(dir->d_name,name);
After the first line, name
and dir->d_name
point to the same memory address. This means you try to add a suffix to the memory where dir->d_name
is located.
You cannot expect that memory to be large enough to hold your suffix. (But in this case this does not cause the problem as your file names seem to be short enough)
Also your update will affect both name
and dir->d_name
in the same way which makes renaming pointless because you try to rename getusage.txt.enc
to getusage.txt.enc
A possible solution could be:
char name[sizeof(dir->d_name)+4];
while ((dir = readdir(d)) != NULL)
{
strcpy(name, dir->d_name);
printf("File Found:%s\n",name);
strcat(name,".enc");
val=rename(dir->d_name,name);
Upvotes: 5
Reputation: 1
Since name
may not have a larger size, strcat(name,".enc");
will may write past that size and causes UB. As others point out, this does not cause the ENOENT error you get (assuming you use linux).
To fix that you have to create a new, large enough buffer and copy the new name to it. This would also fix the error you get because this way you do not overwrite the old name.
Upvotes: 0
Reputation: 4307
I think perhaps you're assuming that name=dir->d_name
creates some new piece of data called name
. It's an easy enough mistake to make, because in many programming languages that's exactly what would happen. In C though, you've just set a pointer called name
to refer to the existing data called d_name
.
If you want to append something to d_name
, you probably need to copy it to a char *
that references a piece of storage large enough to hold it, and the suffix, and the terminating null, and then copy the suffix onto the end of that new storage. Something like:
char *new_name = malloc (strlen (dir->d_name) + strlen (suffix) + 1);
strcpy (new_name, dir->d_name);
strcat (new_name, suffix);
...
free (new_name);
Probably there are many other ways to achieve the same thing. The fundamental point is that assigning pointer types in C does not allocate or duplicate storage.
Upvotes: 1
Reputation: 1589
Your name
& dir->d_name
have the same address. Hence strcat(name,".enc");
will update both name
& dir->d_nam
e and the source will have the prefix '.enc'
Upvotes: 1