I have some problem with fopen() function in C.
I'am parsed directory and put all the paths to char array(char**). After that i should to open all these files. And...
fopen returns "No such file or directory" for some files. And I Am really don't understand, why.
- All paths are right. I checked it.
- I have all privileges to
open these files.
- If I copy path to file from error log and try
to open only this file via my programm - it works.
- Others
programms don't work with these files(i think).
What can I do wrong?
int main(int argc, char *argv[]){
char** set = malloc(10000*sizeof(char*));
char* path = argv[1];
listdir(path, set); /* Just parse directory. Paths from the root. No problem in this function. all paths in the variable "set" are right */
int i=0;
while(i<files){ /* files is number of paths */
FILE* file = fopen(set[i++],"rb");
fseek(file, 0L, SEEK_END);
int fileSize = ftell(file);
rewind(file);
/*reading bytes from file to some buffer and close current file */
i++;
}
}
- You increments 'i' twice. May be mistakenly?
- You can get file size w/o open it using stat().
- ftell() returns "long", don't cast it in "int" as it can be shorten and you loose correct value.
Try this code:
#include <stdio.h>
#include <sys/stat.h>
/* example of listdir, replace it with your real one */
int listdir(const char *path, char *set[])
{
set[0] = "0.txt";
set[1] = "1.txt";
set[2] = "2.txt";
set[3] = "3.txt";
set[4] = "4.txt";
return 5;
}
int main(int argc, char *argv[]) {
int files;
char *path = argv[1];
char **set = malloc(1000 * sizeof(char *));
files = listdir(path, set);
for (int i = 0; i < files; i++) {
struct stat st;
stat(set[i], &st);
printf("FileSize of %s is %zu\n", set[i], st.st_size);
}
free(set);
}
(I am guessing you are on some Posix system, hopefully Linux)
Probably your listdir
is wrong. FWIW, if you use readdir(3) in it, you need to concatenate the directory name and the file name (with a /
in between, perhaps using snprintf(3) or asprintf(3) for that purpose).
But surely,
FILE* file = fopen(set[i++],"rb"); ////WRONG
is doubly wrong. First, you are incrementing i++
twice (and here it is too early). Then, you should read fopen(3) and handle the failure case, at least with:
char* curpath = set[i];
assert (curpath != NULL);
FILE* file = fopen(curpath, "rb");
if (!file) { perror(curpath); exit(EXIT_FAILURE); };
testing the result of fopen
against failure is mandatory. Notice that I am passing the same curpath
to perror(3) on failure.
You may also want to check that your current working directory is what you expect. Use getcwd(2) for that.
Use also strace(1) (on Linux) to understand what system calls are done by your program.