Search code examples
ccs50

"No such file or Directory" but I'm in the directory with the file


I'm trying to work on this problem for CS50 but for some baffling reason it won't even acknowledge that the file I'm trying to run even exists when I'm in the right directory with said file.

env

#include <stdio.h>

int main(int argc, char *argv[])
{
    // Check for command line args
    if (argc != 2)
    {
        printf("Usage: ./read infile\n");
        return 1;
    }

    // Create buffer to read into
    char buffer[7];

    // Create array to store plate numbers
    char *plates[8];

    FILE *infile = fopen(argv[1], "r");

    int idx = 0;

    while (fread(buffer, 1, 7, infile) == 7)
    {
        // Replace '\n' with '\0'
        buffer[6] = '\0';

        // Save plate number in array
        plates[idx] = buffer;
        idx++;
    }

    for (int i = 0; i < 8; i++)
    {
        printf("%s\n", plates[i]);
    }
}

Solution

  • license.c is a source file, that must be compiled into an executable file. license is not the same as license.c.

    The CS50 tool for turning source files into executable files is called make. For example, executing make foo will cause the program to look for a source file called foo.c and produce an executable called foo, assuming no errors occur during compilation (or linking).

    This is described in the Week 1 Lecture, and in various other places, such as Debug.

    In summary, type the following commands in order.

    $ make license
    $ ./license
    

    The $ indicates you are typing these commands into a terminal.


    As for your program:

    • infile should be tested to not be NULL. If it is NULL, the program should probably exit early, otherwise fread will invoke Undefined Behaviour.

    • In plates[idx] = buffer;, buffer decays to a pointer to its first element, and this pointer value is stored in the plates array. There is no copying of the buffer elements, or automatic memory allocation taking place. In effect, you are repeatedly storing a reference to the same array in plates.

      • You should allocate memory in some way to store every plate you read. Either with dynamic memory allocation, or a two-dimensional array (e.g., char plates[8][7];). With the former you will want to copy (strcpy / memcpy) the values of the current buffer to the new memory allocation, and with the latter you can read directly into plates instead.
    • The while loop should additionally check that plates is not full before reading more data from the file. Otherwise, when idx is greater than or equal (>=) to 8, you will invoke more Undefined Behaviour by accessing plates at an out-of-bounds position.