2

Hello mates and sorry for my english! Firstly, could I ask help at this forum with my bugs in case I cant figure out the problem on my own?

So to begin with, i have a file that contains some logs that are structured like that:

2015-07-22 09:07:00 1346144 13.02 25.36 6.606 4.012 0.845 26.3
2015-07-22 09:08:00 1346145 13.02 25.38 6.656 4.057 0.848 26.4
2015-07-22 09:09:00 1346146 13.02 25.43 6.667 4.086 0.849 26.45
2015-07-22 09:10:00 1346147 13.02 25.46 6.663 4.109 0.851 26.44
2015-07-22 09:11:00 1346148 13.02 25.5 6.657 4.131 0.856 26.51
2015-07-22 09:12:00 1346149 13.02 25.53 6.693 4.17 0.862 26.53
2015-07-22 09:13:00 1346150 13.02 25.56 6.723 4.205 0.865 26.71
2015-07-22 09:14:00 1346151 13.02 25.6 6.734 4.233 0.866 26.64

So I managed to pass each line to a Log structure that which looks like:

typedef struct Log {
    char    field1[11]  ;
    char    field2[9]   ;
    int     field3      ;
    float   field4      ;
    float   field5      ;
    float   field6      ;
    float   field7      ;
    float   field8      ;
    float   field9      ;
}log_t, *plog;

I managed to pass a line but i get in trouble when I try to pass more lines. I try to make a pointer pointer to this structure as i know that arrays are pointers. This is my code:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

typedef struct Log {
    char    field1[11]  ;
    char    field2[9]   ;
    int     field3      ;
    float   field4      ;
    float   field5      ;
    float   field6      ;
    float   field7      ;
    float   field8      ;
    float   field9      ;
}log_t, *plog;

FILE* OpenFile(const char* path) 
{
    FILE* file = NULL;
    file = fopen(path, "r");
    if (file == NULL)
        printf("File cant be opened\n");
    else
        printf("File is opened\n");
    return file;
}

plog CreateLog(FILE* file)
{
    plog log = (plog)malloc(sizeof(log));
    fscanf(file, "%s", log->field1);
    fscanf(file, "%s", log->field2);
    fscanf(file, "%d", &(log->field3));
    fscanf(file, "%f", &(log->field4));
    fscanf(file, "%f", &(log->field5));
    fscanf(file, "%f", &(log->field6));
    fscanf(file, "%f", &(log->field7));
    fscanf(file, "%f", &(log->field8));
    fscanf(file, "%f", &(log->field9));
    return log;
}

void PrintLog(log_t log)
{
    printf("%s", log.field1);
    printf("%s", log.field2);
    printf("%d", log.field3);
    printf("%f", log.field4);
    printf("%f", log.field5);
    printf("%f", log.field6);
    printf("%f", log.field7);
    printf("%f", log.field8);
    printf("%f", log.field9);
}

int main()
{
    FILE* file;
    file = OpenFile("DataMeteoE4.txt");
    //plog log = CreateLog(file);
    plog* logs;
    logs = (plog*)malloc(sizeof(log_t) * 10);
    for (int i = 0; i < 10; i++)
    {
        logs[i] = CreateLog(file);
    }
    //PrintLog(*log);
    fclose(file);
    return 0;
}

It crashes with exception: " .exe has triggered a breakpoint" Can anyone help me pls

  • `*(logs+i*sizeof(log_t))` is needlessly complicated and also wrong. Just use it like an array `logs[i] =` – UnholySheep Dec 28 '19 at 16:20
  • It doesnt works either and i get the same error but you are right. it is really simplier – TomatoPaste Dec 28 '19 at 16:22
  • 1
    `plog log = (plog)malloc(sizeof(log));` should also be `plog log = malloc(sizeof(*log));` – UnholySheep Dec 28 '19 at 16:25
  • I have to allocate memory for all the struct so it might be sizeof(log_t) i guess, no? – TomatoPaste Dec 28 '19 at 16:31
  • `sizeof *log` and `sizeof(log_t)` evaluate to the same thing, choose whichever one you feel is better readable – UnholySheep Dec 28 '19 at 16:32
  • I found the mistake in main function plog* logs; logs = (plog*)malloc(sizeof(plog) * 10); plog is evaluate to log_t* or Log* – TomatoPaste Dec 28 '19 at 16:34
  • In array of Logs i have to allocate memory for pointer, and not for struct as i did in createlog – TomatoPaste Dec 28 '19 at 16:35
  • Obligatory reference to https://stackoverflow.com/q/605845/2988730 – Mad Physicist Dec 28 '19 at 17:08
  • "as i know that arrays are pointers" ... wrong! I suggest you read section 6 of the [comp.lang.c faq](http://c-faq.com/). The truth is "in many circumstances arrays are converted to pointers" and "using arrays notation with pointers is perfectly legal". – pmg Dec 28 '19 at 17:11
  • OT: regarding statements like: `printf("File cant be opened\n");` 1) error messages should be output to `stderr`, not `stdout`, similar to: `fprintf( stderr, "my error message\n" );` 2) when the error comes from a C library function, then should also output the text reason the system thinks the error occurred. The function: `perror()` is made for posting those two items to `stderr`. – user3629249 Dec 29 '19 at 13:11
  • regarding: `printf("File cant be opened\n");` This is an unrecoverable error. Therefore, the code should call `perror( "fopen failed" );` followed by: `exit( EXIT_FAILURE );` I.E. the code must not continue to execute as if the call to `fopen()` was successful. – user3629249 Dec 29 '19 at 13:14

1 Answers1

-2

I have changed the code, which should now work! Please see comments to see what has been changed.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//////////////////////////////////////////
// I don't know what was the use of plog,
// so removed it.
//////////////////////////////////////////
typedef struct Log {
    char    field1[11]  ;
    char    field2[9]   ;
    int     field3      ;
    float   field4      ;
    float   field5      ;
    float   field6      ;
    float   field7      ;
    float   field8      ;
    float   field9      ;
} log_t;

FILE* OpenFile(const char* path) 
{
    FILE* file = fopen(path, "r");
    return file;
}

log_t CreateLog(FILE* file)
{
    //////////////////////////////////////////
    // Change in format for reading string
    // Reading into local variable log and returning it
    //////////////////////////////////////////
    log_t log;
    memset(&log, 0, sizeof(log_t));
    fscanf(file, "%11s", log.field1);
    fscanf(file, "%8s", log.field2);
    fscanf(file, "%d", &(log.field3));
    fscanf(file, "%f", &(log.field4));
    fscanf(file, "%f", &(log.field5));
    fscanf(file, "%f", &(log.field6));
    fscanf(file, "%f", &(log.field7));
    fscanf(file, "%f", &(log.field8));
    fscanf(file, "%f", &(log.field9));
    return log;
}

void PrintLog(log_t log)
{
    //////////////////////////////////////////
    // Added spaces in between fields
    //////////////////////////////////////////
    printf("%.11s ", log.field1);
    printf("%.8s ", log.field2);
    printf("%d ", log.field3);
    printf("%f ", log.field4);
    printf("%f ", log.field5);
    printf("%f ", log.field6);
    printf("%f ", log.field7);
    printf("%f ", log.field8);
    printf("%f\n", log.field9);
}

int main()
{
    FILE* file = OpenFile("DataMeteoE4.txt");
    //////////////////////////////////////////
    // Removed this from OpenFile function and
    // put it here. Also exit from program if
    // open fails.
    //////////////////////////////////////////
    if (file == NULL) {
        printf("File can't be opened\n");
        return 1;
    }
    else
        printf("File is opened\n");

    //////////////////////////////////////////
    // Change of array size from 10 to 8 in 
    // both malloc and loop condition, since 
    // there were 8 lines in sample input
    //////////////////////////////////////////
    log_t* logs = (log_t*) malloc(sizeof(log_t) * 8);
    for (int i = 0; i < 8; i++)
    {
        logs[i] = CreateLog(file);
        PrintLog(logs[i]);
    }
    fclose(file);
    return 0;
}
kiner_shah
  • 3,939
  • 7
  • 23
  • 37