0

In this demo project I am failing to use pointer strings. My file reader tokens are not iterating correctly when moving data from tokens to pointer strings, but first I am experiencing issues causing faulty strings when trying to pass on data to the addCarFunction().

enum Tire { SOMMERDAEK, VINTERDAEK };
enum Material { STAAL, ALU };

//struct that holds car data
//Using typedef to make the struct a datatype
typedef struct car{
    char *regNumber;
    char *carBrand;
    enum Tire tire;
    enum Material material;
    int timeLeft;
    struct car *nextCarPtr;
} Car;

//typedef struct car Car;
typedef Car *CarPtr;


void addCarFunction(CarPtr *firstPtr, CarPtr *lastPtr, char *newRegNumber, char *newCarBrand, char *newTire, char *newMaterial) {
    //Allocating memory for the current car
    CarPtr newCarPtr = malloc(sizeof(Car));
    printf("addCarFunction received: %s\n", newRegNumber);
    if (newCarPtr != NULL) {
        //Inserts given values into car struct
        newCarPtr -> regNumber = newRegNumber;
        newCarPtr -> carBrand = newCarBrand;
        //Converting values to enum
        if (newTire == "sommerdæk") {
            newCarPtr -> tire = SOMMERDAEK;
        }

        //if "sommerdæk" is spelled wrong it will be replaced with "vinterdæk". There is no error handling here.
        else {
            newCarPtr -> tire = VINTERDAEK;
        }
        if (newMaterial == "alu") {
            newCarPtr -> material = ALU;
        }
        //Similar to before. There is no error handling here.
        else {
            newCarPtr -> material = STAAL;
        }

        //Calculating wait time
        if (newCarPtr -> tire == SOMMERDAEK && newCarPtr -> material == ALU){
            newCarPtr -> timeLeft = 20;
        }
        else if (newCarPtr -> tire == SOMMERDAEK && newCarPtr -> material == STAAL){
            newCarPtr -> timeLeft = 18;
        }
        else {
            newCarPtr -> timeLeft = 15;
        }

        //Placing current car in the back of the line using pointers
        newCarPtr -> nextCarPtr = NULL;

        //Checking if the queue is empty
        if (*firstPtr == NULL) {
            *firstPtr = newCarPtr;
        }
        else {
            // *lastPtr needs to be in () because else the dereferencing will not work
            // If not empty, the currently last known car is set to point to the next car
            (*lastPtr) -> nextCarPtr = newCarPtr;
        }
        // The currently last known pointer is set to the new car
        *lastPtr = newCarPtr;
    }
    //If no more memory print an error message.
    else {
        printf("%s Could not be added to the queue. There is no more memory left", newRegNumber);
    }
}


void readFileFunction(CarPtr *firstPtr, CarPtr *lastPtr) {
    FILE *inputFilePtr;
    char *readRegNumber;
    char *readCarBrand;
    char *readTire;
    char *readMaterial;
    inputFilePtr = fopen("input.txt", "r");
    char buffer[35];
    while((fgets(buffer, 128, inputFilePtr))!= NULL) {
        printf("%s", buffer);
        char *tokenPtr = strtok(buffer, " ");
        int i = 0;
        while(tokenPtr != NULL) {
            printf("%s\n", tokenPtr);
            switch(i) {
                case 0:
                    readRegNumber = tokenPtr;
                    break;
                case 1:
                    readCarBrand = tokenPtr;
                    break;
                case 2:
                    readTire = tokenPtr;
                    break;
                case 3:
                    readMaterial = tokenPtr;
                    break;
            }
            i++;
            tokenPtr = strtok(NULL, " ");
        }
        addCarFunction(firstPtr, lastPtr, readRegNumber, readCarBrand, readTire, readMaterial);
    }
    fclose(inputFilePtr);  //Close the file
}


int main() {
    CarPtr firstPtr = NULL;
    CarPtr lastPtr = NULL;
    printf("Started...\n");
    char testString[7] = "BB44556";
    char *testStringPtr = "Ford";


    readFileFunction(&firstPtr, &lastPtr);

    addCarFunction(&firstPtr, &lastPtr, "AB11523", "Citroen", "vinterdæk", "alu");
    //printQueue(firstPtr);
    addCarFunction(&firstPtr, &lastPtr, "AA22523", testStringPtr, "sommerdæk", "stål");
    //printQueue(firstPtr);
    addCarFunction(&firstPtr, &lastPtr, "AA33523", "Volvo", "sommerdæk", "alu");
    addCarFunction(&firstPtr, &lastPtr, testString, "Suzuki", "sommerdæk", "stål");
    //printf("Removed %s from the queue.", removeFirstCar(&firstPtr, &lastPtr));
    
    printQueueFunction(firstPtr);
//    optionsFunction(&firstPtr, &lastPtr);

    return 0;
}

As you can see I have experimented with different ways of sending data when adding cars to the queue manually in the main() function. But the issue occurs when trying to add data from a file through the readFileFunction().

Can someone help me find out where I go wrong - because I feel like I have searched and not found an answer - or I have not used the correct search terms :-/

Any help would be much appreciated.

To see the code running you can see the full code and output here: https://onlinegdb.com/2BLfwB_-o

  • 1
    `newTire == "sommerdæk"` is not how we compare strings in C. Use `strcmp`. I didn't look any further. – Cheatah Nov 20 '22 at 04:40
  • Style guide: the dot `.` and arrow `->` operators bind very tightly because they are [postfix operators](http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3). They should not be written with spaces around them. Writing `newCarPtr -> tire` is not idiomatic C and indicates that the coder is a tyro (newbie). Use `newCarPtr->tire`. – Jonathan Leffler Nov 20 '22 at 05:07
  • Note that since you don't make copies of the strings, the details of each newly read car will overwrite the strings for all the previously read cars, which is not what you want at all. You probably need to use `strdup()` — if you don't have it available, you can write your own easily: `char *strdup(const char *str) { size_t len = strlen(str) + 1; char *rv = malloc(len); if (rv != NULL) memmove(rc, str, len); return rv; }` – Jonathan Leffler Nov 20 '22 at 05:12

0 Answers0