1

Hello and good day to all of you. I've encountered a problem which I've spent a good 3 hours on, not finding a solution. I want to extract data from a text file and and put it in different pointers that have corresponding names.

For example : QUA_1 goes in qua1, etc...

Everytime I launch the code, I get the "wntdll.pdb not loaded".

The text file's layout is as such :

Syntax version=4
Wed Mar 17 12:26:34 2021
Starting process (10000000 clocks per sec)

LogRawData=false
VarHeader=1
D:      Accelerometer_1[0]  Accelerometer_2[0]  Gyroscope_1[0]  Gyroscope_2[0]  QUA_1[0]    QUA_2[0]    Accelerometer_1[1]  Accelerometer_1[2]  Accelerometer_2[1]  Accelerometer_2[2]  Gyroscope_1[1]  Gyroscope_1[2]  Gyroscope_2[1]  Gyroscope_2[2]  QUA_1[1]    QUA_1[2]    QUA_1[3]    QUA_2[1]    QUA_2[2]    QUA_2[3]
D:  time(ms)    (0x200000b8,5)  (0x20000054,5)  (0x20000048,5)  (0x20000060,5)  (0x20000028,5)  (0x200000a8,5)  (0x200000bc,5)  (0x200000c0,5)  (0x20000058,5)  (0x2000005c,5)  (0x2000004c,5)  (0x20000050,5)  (0x20000064,5)  (0x20000068,5)  (0x2000002c,5)  (0x20000030,5)  (0x20000034,5)  (0x200000ac,5)  (0x200000b0,5)  (0x200000b4,5)
D:  0.31    -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  2.96    -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  5.46    -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  7.91    -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  10.65   -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  13.64   -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  16.42   -685    -670    16  2   1529    8263    -549    445 -707    81  -3  12  10  -19 -7221   -4455   13932   -10991  -795    8873
D:  18.89   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873
D:  21.55   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873
D:  24.03   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873
D:  26.49   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873
D:  29.03   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873
D:  31.49   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873
D:  33.97   -714    -680    8   4   1531    8263    -543    460 -735    81  24  3   -9  0   -7217   -4458   13933   -10991  -795    8873

Note : there are more lines in the text file but all of them are similar to the "D: ..." lines apart from the numbers changing.

As for the code :

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>

#define MAX_BLOCK_SIZE 100
uint32_t MAX_INDEX = MAX_BLOCK_SIZE - 1;

.
.
.

void getData(double* time_t, uint32_t** acc1, uint32_t** acc2, uint32_t** gyro1, uint32_t** gyro2, uint32_t** qua1, uint32_t** qua2)
{
    /******************* TEMPORARY SECTION *******************/
    // char ch;
    FILE* fichier;
    errno_t err = 1;

    while (err == 1)
    {
        // Open the file in READ mode ==> avoid modifying the data
        err = fopen_s(&fichier, "Dan_AHAHAHHAHA.txt", "r");

        //perror("Error while opening the file.\n");
    }

    // Keep going until you reach the end of the document
    //while ((ch = fgetc(fichier)) != EOF)
    //  printf("%c", ch);

    uint32_t i = 0;
    //uint32_t indice_phase1 = 0;

    // Data processing loop
    while (feof(fichier) != 1)
    {
        // fseek allows to get each line separately
        fseek(fichier, 3, 0);

        // Then, we get the values from the line and separate them into their corresponding pointers
        fscanf_s(fichier, "%lf%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu%lu",
            &time_t[i], &acc1[0][i], &acc2[0][i], &gyro1[0][i], &gyro2[0][i], &qua1[0][i], &qua2[0][i],
            &acc1[1][i], &acc1[2][i], &acc2[1][i], &acc2[2][i], &gyro1[1][i], &gyro1[2][i], &gyro2[1][i],
            &gyro2[2][i], &qua1[1][i], &qua1[2][i], &qua1[3][i], &qua2[1][i], &qua2[2][i], &qua2[3][i]);
        i++;

        // when there's no more space in the pointers, they need to be reallocated to bigger pointers
        if (i == MAX_INDEX)
        {
            IncreaseTimeSize(time_t, MAX_INDEX);
            Increase_GyroAccelero_Size(acc1, MAX_INDEX);
            Increase_GyroAccelero_Size(acc2, MAX_INDEX);
            Increase_GyroAccelero_Size(gyro1, MAX_INDEX);
            Increase_GyroAccelero_Size(gyro2, MAX_INDEX);
            IncreaseQuaternionSize(qua1, MAX_INDEX);
            IncreaseQuaternionSize(qua2, MAX_INDEX);
            MAX_INDEX += MAX_BLOCK_SIZE;
        }
    }

    // Deallocate excesse dynamic memory to the system for better performance
    ResizeQuaternionSize(qua1, MAX_INDEX, i);
    ResizeQuaternionSize(qua2, MAX_INDEX, i);
    Resize_GyroAccelero_Size(acc1, MAX_INDEX, i);
    Resize_GyroAccelero_Size(acc2, MAX_INDEX, i);
    Resize_GyroAccelero_Size(gyro1, MAX_INDEX, i);
    Resize_GyroAccelero_Size(gyro2, MAX_INDEX, i);
    Resize_Time_Size(time_t, MAX_INDEX, i);

    fclose(fichier);

    /******************* TEMPORARY SECTION *******************/
/*************** Part 2 : Quaternion Normalisation ***************/

    double norme_qua1 = 0;
    double norme_qua2 = 0;

    for (uint8_t j = 0; j < i; j++)
    {
        norme_qua2 = sqrt(pow(qua2[0][j], 2) + pow(qua2[1][j], 2) + pow(qua2[2][j], 2) + pow(qua2[3][j], 2));
        norme_qua1 = sqrt(pow(qua1[0][j], 2) + pow(qua1[1][j], 2) + pow(qua1[2][j], 2) + pow(qua1[3][j], 2));
        qua1[0][j] = qua1[0][j] / norme_qua1;
        qua1[1][j] = qua1[1][j] / norme_qua1;
        qua1[2][j] = qua1[2][j] / norme_qua1;
        qua1[3][j] = qua1[3][j] / norme_qua1;

        qua2[0][j] = qua2[0][j] / norme_qua2;
        qua2[1][j] = qua2[1][j] / norme_qua2;
        qua2[2][j] = qua2[2][j] / norme_qua2;
        qua2[3][j] = qua2[3][j] / norme_qua2;
    }
}

The "resizing" and "increasing" function have about the same layout as the one below :


/********************************************************************************************\
|*                  Resize pointers for Accelerometers and Gryscopes                        *|
|* This function is for deallocating excess memory from the pointers containing the data    *|
|* retrieved from the patient or file. This one's for triple pointers on the uint32_t type. *|
\********************************************************************************************/

void Resize_GyroAccelero_Size(uint32_t** name, uint32_t max_index, uint32_t size)
{
    /*
     * The Realloc function can FAIL!!! Thus, it is MANDATORY to use a temporary variable
     * and reallocate in cas of failure. If not, data can be OVERWRITTEN, and the data
     * processing will be wrong, resulting in wrong moves!!!
     */

    // Create temporary variable
    uint32_t** tmp = (uint32_t**)malloc(sizeof(uint32_t*) * 3);

    // While memory is not allocated...
    while (&tmp == NULL)
    {
        // Print in the console if an error occurs
        perror("realloc-*time");

        // Create temporary variable until memory is allocated...
        uint32_t** tmp = (uint32_t**)malloc(sizeof(uint32_t*) * 3);
        for (uint8_t i = 0; i < 3; i++)
            *tmp[i] = (uint32_t)realloc(*name, size * sizeof(uint32_t));
    }
    *name = (uint32_t*)tmp;  /* now assign the reallocated block to your pointer */
}

void Increase_GyroAccelero_Size(uint32_t** name, uint32_t max_index) // slightly changed to test
{
    /*
     * The Realloc function can FAIL!!! Thus, it is MANDATORY to use a temporary variable
     * and reallocate in cas of failure. If not, data can be OVERWRITTEN, and the data
     * processing will be wrong, resulting in wrong moves!!!
     */

    // Create temporary variable
    uint32_t** tmp = (uint32_t**)malloc(sizeof(uint32_t*) * 3);

    // While memory is not allocated...
    while (&tmp == NULL)
    {
        // Print in the console if an error occurs
        perror("realloc-*time");

        // Create temporary variable until memory is allocated
        for (uint8_t i = 0; i < 3; i++)
            *tmp[i] = (uint32_t)realloc(*name, (max_index + 1 + MAX_BLOCK_SIZE) * sizeof(uint32_t));
    }
    *name = (uint32_t*)tmp;  /* now assign the reallocated block to your pointer */
}

Do not mind the agressive commenting I've been doing, my teachers like it this way.

Dan Guilas
  • 23
  • 3
  • " I want to extract data from a text file and sort it out and put it in different pointers that have corresponding names." - That description is unclear, almost to the extent of being meaningless. – Peter Apr 02 '21 at 12:57
  • 1
    "// fseek allows to get each line separately"`fseek(fichier, 3, 0);` I don't see how that gives you a new line? – Irelia Apr 02 '21 at 12:59
  • Nevermind this wrong comment, it is to skip the "D: " part at the beginning of each line I think. Not to sure though, since it is "translated" code from matlab. – Dan Guilas Apr 02 '21 at 13:01
  • You are using `feof` incorrectly. https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – William Pursell Apr 02 '21 at 13:28
  • That is not what `fseek` does. `fseek(fichier, 3, 0);` will either move you to the 3rd byte of the file, (attempt to) move 3 bytes past the end of the file, or move 3 bytes past the current location. You should never use `0`: use SEEK_SET, SEEK_END, or SEEK_CUR. – William Pursell Apr 02 '21 at 13:31
  • Almost certainly, SEEK_SET is 0, so your fseeks are always moving you to the 3rd byte of the file. (Or they are failing; you should check). – William Pursell Apr 02 '21 at 13:33
  • Thanks for this information William. I will look into that. – Dan Guilas Apr 02 '21 at 13:39

1 Answers1

1

Your primary loop is wrong. There is no need for fseek here, and it is being used incorrectly. fseek knows nothing about lines; it will position the file pointer in the byte stream relative to the beginning of the file, the end of the file, or the current position. Also, the present usage of feof is incorrect. (See Why is “while ( !feof (file) )” always wrong?)

You should change your main loop to look something like:

    while( 21 == fscanf(fichier, "D: %lf %lu %lu %lu %lu %lu ... ",
        time_t + i, acc1[0] + i, ... ) ){ ... }

Note that the spaces in the format stream are purely cosmetic. They won't change how fscanf works, but they make the code a lot easier on the eyes. You can use fscanf_s if you prefer, but it's non-standard and I've modified the answer to use the standard function.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Ok! Now it does not give me the error but an exception is lifted at this line : `norme_qua2 = sqrt(pow(qua2[0][j], 2) + pow(qua2[1][j], 2) + pow(qua2[2][j], 2) + pow(qua2[3][j], 2));` Do you happen to know why? – Dan Guilas Apr 02 '21 at 13:52
  • I would guess perhaps one of those `sqrt` has a negative value passed. But that's just a guess. – William Pursell Apr 02 '21 at 13:57
  • After a few tests, it seems like the pointers are null, since they contain the 3452816845 number, which I guess means they not initialized. Still looking into the matter. – Dan Guilas Apr 02 '21 at 14:01