1

I want to read data from txt file and save those data in variables not just print output. How do I save those data from text file in variables? I tried like this and it did not work out:

int value1 ; 
object2->value =&value1 ; 
*(object2->value) = value1 ; 

My txt file looks like this:

INT 
A
5

and my code looks like this:

#include <stdio.h>
#include <stdlib.h> // For exit()

struct variable {
    char type[10];
    char name[10];
    int value;
};

int main(){

struct variable *object2=malloc(sizeof(struct variable));

    FILE * file= fopen("input.txt", "rb");
    if (file != NULL) {
        fread(object2, sizeof(struct variable), 1, file);
        fclose(file);
    }
    
    int value1 ;
    object2->value =&value1 ;
    *(object2->value) = value1 ;

    printf("%d\n",value1);

    printf("%s/%s/%d\n",object2->type,object2->name,object2->value);
    
    
    }
6
  • 1
    Welcome to StackOverflow! Please take the tour and read "How to Ask" to learn how this site works. -- Did you consider to use fgets() and sscanf() for the task? If you use fread(), you need your input file to be binary compatible to your structure layout. Commonly it cannot be a text file. -- Oh, and you did not ask a question. Commented Sep 5, 2021 at 17:16
  • 1
    You stated your goal, but not your problem. You need to ask a specific question about what you're having trouble with. Commented Sep 5, 2021 at 17:43
  • @TomKarzes I dont know how to save these values in variables because I dont know how to dereference these pointers for example here I tried like this: int value1 ; object2->value =&value1 ; *(object2->value) = value1 ; and it didnt work Commented Sep 5, 2021 at 17:48
  • @PPProgramer Edit your post to include your question. Commented Sep 5, 2021 at 17:49
  • I will in a few seconds when I correct everything, I will include solution. I am new here so sorry for bad formating. Commented Sep 5, 2021 at 17:53

3 Answers 3

2

File format:

CHAR
B
6
INT
A
5
FLOAT
C
7

This is my solution:

#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h>

#define BUFF_SIZE 1024
#define NAME_TYPE_SIZE 10
#define VALUE_SIZE 20

#define NOT_ENOUGH_MEMORY 1
#define CANT_OPEN_FILE 2
#define FILE_ENDED 3
#define TOO_BIG_STR 4
#define CANT_FORMAT_VALUE 5
#define NOT_FOUND_LINE 6

#define SEARCH_NAME "A"

#pragma warning(disable : 4996) // for vs

struct variable {
    char type[NAME_TYPE_SIZE];
    char name[NAME_TYPE_SIZE];
    int value;
};

int find_var_in_file(char* file_path, char* find_name, struct variable* dest);

int main()
{
    struct variable* object2 = malloc(sizeof(struct variable));

    if (NULL == object2)
    {
        printf("not enough memory");
        return NOT_ENOUGH_MEMORY;
    }

    int error = find_var_in_file("input.txt", SEARCH_NAME, object2);

    if (CANT_OPEN_FILE == error)
    {
        return printf("can't open file");
    }

    if (error == 0)
    {
        // Printing data to check validity
        printf("read: type: %s name: %s value: %d", object2->type, object2->name, object2->value);
        int a = object2->value;
        // do stuff with a
    }
    else
    {
        if (error == NOT_FOUND_LINE)
        {
            printf("not find the var \"" SEARCH_NAME "\" in the file");
        }
        else
        {
            printf("error reading the file. error code: %d", error);
        }
    }

    free(object2);

    return 0;
}

int read_line(char* buffer, int buffer_size, char* dest, int dest_size, FILE* stream)
{
    if (!fgets(buffer, buffer_size, stream))
    {
        return NOT_FOUND_LINE;
    }

    int read_len = strlen(buffer);

    if ('\n' == buffer[read_len - 1])
    {
        if (read_len == 1)
        {
            return NOT_FOUND_LINE;
        }
        buffer[read_len - 1] = '\0'; // remove "\n" in the end
    }

    if (dest_size <= strlen(buffer)) // last chat is null
    {
        return TOO_BIG_STR;
    }

    strcpy(dest, buffer);

    // clear the read
    memset(buffer, '\0', read_len);

    return 0;
}

int find_var_in_file(char* file_path, char* find_name, struct variable* dest)
{
    char file_buffer[BUFF_SIZE] = { 0 }; // Buffer to store data
    FILE* stream = fopen(file_path, "r");
    if (NULL == stream)
    {
        return CANT_OPEN_FILE;
    }

    int error = 0;
    while (1)
    {
        // read type
        int read_type_result = read_line(file_buffer, BUFF_SIZE, dest->type, NAME_TYPE_SIZE, stream);
        if (read_type_result != 0)
        {
            error = read_type_result;
            break;
        }

        int read_name_result = read_line(file_buffer, BUFF_SIZE, dest->name, NAME_TYPE_SIZE, stream);

        if (read_name_result != 0)
        {
            error = read_name_result;
            break;
        }

        char value_buffer[VALUE_SIZE] = { 0 };
        int read_value_result = read_line(file_buffer, BUFF_SIZE, value_buffer, VALUE_SIZE, stream);
        if (read_value_result != 0)
        {
            error = read_value_result;
            break;
        }

        if (0 == strcmp(find_name, dest->name))
        {
            if (1 != sscanf(value_buffer, "%d", &dest->value))
            {
                error = CANT_FORMAT_VALUE;
            }
            break;
        }
    }

    fclose(stream);

    return error;
}

You just need to call the function find_var_in_file like in main. I loop over all the lines of the file and search for the var name. If have formating error or not find the name of the var in the file return the error code.

Sign up to request clarification or add additional context in comments.

10 Comments

This program will generate several warnings: return with no value, in function returning non-void; format %s expects argument of type char *, but argument {3,4} has type char (*)[5]; unused variable count. Additionally: &file_buffer in the call the fread may work, but typically this would be written as file_buffer, as an array will already decay to a pointer-to-the-first-element when passed as a function argument.
"Also, sscanf is very dangerous because of buffer overflow." -- which you have the opportunity to address by using a maximum field width specifier to limit the amount of data read into your arrays (e.g., "%4s").
Finally: you are attempting to read 1024 bytes from the file without checking either your return size from fread, or your conversion matches from sscanf for validity.
@Oka Thanks you for your feedback! I tried to address the warnings. Also What do you mean by: "format %s expects argument of type char , but argument {3,4} has type char ()[5]" Can you give me an example how I fix that in my code?
Slightly verbose: object2->type has the type char [10] (array of 10 char), which means &object2->type has the type char (*)[10] (pointer to array of 10 char). The *scanf specifier "%s (and "%[]") expect a char * (pointer to char). When used as a function argument, type char [N] will naturally decay to char *. Thusly: &object2->type should be object2->type, and &object2->name should be object2->name. (Note that it currently works because ...reasons, but is generally bad form).
|
0

If the file you are trying to read is a text file (which it is in your case), then use fgets() to read its content. Also, if its content has a consistent format, then consider using sscanf() to do your parsing.

I don't understand why you are using a pointer to struct variable to save data. You can simply use a struct variable object and access its fields with .

Your code should look something like that:

#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h> // for strlen()

struct variable {
    char type[10];
    char name[10];
    int value;
};

int main()
{
    FILE *file = fopen("input.txt", "r");
    if (!file) {
        fprintf(stderr, "Could not read file\n");
        return 1;
    }

    struct variable object2;
    char buffer[1024];

    while (fgets(buffer, 1024, file)) {
        if (sscanf(buffer, "%9s %9s %d", object2.type, object2.name, &object2.value) != 3) {
            fprintf(stderr, "Error parsing file\n");
            fclose(file);
            return 1;
        }

        printf("%s %s %d\n", object2.type, object2.name, object2.value);
    }

    fclose(file);
}

Now, if you want to store all the lines of your file into variables to use them later, then first you need to count the number of lines in your file (let's call it n) and second, allocate a dynamic array of size n.

1 Comment

Thank you. I will try to do like this.
0
fscanf(file,"%s\n%s\n%d\n",object2->type,object2->name,&object2->value);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.