cstringfilefopen

fopen() is unable to open file


I am trying to open a file and read the contents of it. But, I am currently stuck on just trying to open it.

Here is my code:

void read_contents(char* file_path)
{
    printf("\nOriginal path: %s\n", file_path);

    // Trying to prefix the path with "." to indicate that the path is relative.
    char prefix[1024] = ".";
    
    strcat(prefix, file_path);

    // Printing to make sure that prefix contains correct path.
    printf("\nPath after concatenating: %s\n", prefix);

    FILE* file = fopen(prefix, "r");

    if (file == NULL)
    {
       perror("Error");
    
       // Close the file and stop the function.
       fclose(file);
       return;
    }


    // Code to read the file...
    // ...
    // Code to read the file...


    fclose(file);
}

Here is the output: (Keep in mind that it does not even reach the reading part)

Original path: /input_files/file_1.txt

Path after concatenating: ./input_files/file_1.txt

Error: no such file or directory

Here is my directory structure:

root:

executable
input_files (this is a folder)
  file_1.txt

The executable is located at the same level as the folder named "input_files". Inside the input_files is where the text file is located.

Additional things:

  1. I am running the correct executable from the terminal.
  2. The path is correct when passing to the function.
  3. The structure and names of my folders and files are correct.
  4. The permissions are correct for accessing and reading files.
  5. The "." is added to the beginning of the string correctly.

With all this I still get an error saying no such file or directory. Can anyone please tell me what I am missing?


Solution

  • After reading all possible and common solutions in this kind of cases, which didn't work in your case, my only guess can be the malformed C-string passed to function, which can be treated as correct at a first glance. I managed to reproduce the similar problem at my site only having malformed C-string pointer passed to read_contents function.

    The main idea. Let's say you have some statically initialized array in your main function which length is more than that of path of file. In my reproduced case I took byte array with 100 bytes in it.

    char path2[100] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x02};
    

    also I have

    char path[] = "/file.txt" // strlen on this will result in 10 (includes \0)
    

    After I copy the 9 bytes of memory to path2 buffer from path (excluding \0)

    memcpy(path2, path, 9);
    

    Note that I already prepared the replacement for null-terminator byte in path2 - 0x02 byte (it may be any garbage value) After copying the memory from correct buffer to path2 buffer. The resulting string is also correct and if we print it out we see exactly the same string, but, the last byte before null-terminator is 0x02 and not the last symbol from initial path. To be precise the path2 buffer will look like this after memcpy.

    2F 66 69 6C 65 2E 74 78 74 02 00 .... 00
    /  f  i  l  e  .  t  x  t     \0
    

    instead of correct

    2F 66 69 6C 65 2E 74 78 74 00 .... 00
    /  f  i  l  e  .  t  x  t  \0
    

    When try to print out this string you won't even see empty char, as if spare byte does not exist, but for system it matters C:

    When invoking your provided function I get this kind of output

    artyom@artyom:~/workspace/fopenfail$ ./a.out 
    Strlen /file.txt = 10
    Original path: /file.txt
    
    Path after concatenating: ./file.txt
    Error: No such file or directory
    
    
    artyom@artyom:~/workspace/fopenfail$ ls
    a.out  file.txt  main.c
    artyom@artyom:~/workspace/fopenfail$ 
    

    Here is the code I used as possible example

    void read_contents(char* file_path)
    {
        printf("\nOriginal path: %s\n", file_path);
    
        // Trying to prefix the path with "." to indicate that the path is relative.
        char prefix[1024] = ".";
    
        strcat(prefix, file_path);
    
        // Printing to make sure that prefix contains correct path.
        printf("\nPath after concatenating: %s\n", prefix);
    
        FILE* file = fopen(prefix, "r");
    
        if (file == NULL)
        {
           perror("Error");
    
           // Close the file and stop the function.
           return;
        }
    
    
        // Code to read the file...
        // ...
        // Code to read the file...
    
    
        fclose(file);
    }
    
    int main()
    {
            char path[] = "/file.txt";
            char path2[100] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x02};
            memcpy(path2, path, 9);
            printf("Strlen %s = %d", path2, strlen(path2));
    
            read_contents(path2);
            return EXIT_SUCCESS;
    }
    

    Hope this will serve as hint what is wrong in caller function.