skip to Main Content

I got a new problem over here. I’m trying yo compile a C file which I have a section to read info from a file ‘users.txt’ using the _ptr pointer from the FILE structure. The main problem is when I try to compile the file I got the next error in the terminal: error: ‘FILE’ has no member named ‘_ptr’, and downside the error I got this: make: *** [Makefile:16: main.o] Error 1

This is the Makefile:

ASM_SOURCE = functions.asm
C_SOURCE = main.c
OBJ_FILES = main.o functions.o

EXEC_RELEASE = main_release.bin
EXEC_DEBUG = main_debug.bin

release: $(OBJ_FILES)
    gcc -o $(EXEC_RELEASE) $(OBJ_FILES)

debug: $(OBJ_FILES)
    gcc -g -o $(EXEC_DEBUG) $(OBJ_FILES)

main.o: $(C_SOURCE)
    gcc -c $(C_SOURCE)

functions.o: $(ASM_SOURCE)
    nasm -f elf64 -o functions.o $(ASM_SOURCE)

clean:
    rm -f $(OBJ_FILES) $(OBJ_FILES) $(EXEC_DEBUG)

This is the C file:
Please ignore the text written in Spanish, I’m coding this with a friend.

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define LECTURA_COMPLETA 1
#define LECTURA_INCOMPLETA 0

struct Archivos{
    FILE *f1;
    FILE *f2;
    FILE *f3;
};

char** lecturaFile1(struct Archivos file);
char** lecturaFile2(struct Archivos file);
char** lecturaFile3(struct Archivos file);

int main(void)
{
    /// Menu variables
    int MenuUserOn = 1;
    int menu_input, user_input;

    /// User variables
    int number_account, saldoEnCuenta; // Pruebas
    char **users, **pins, **saldos; // Estos buffers tendr�n nuestra informaci�n
    struct Archivos f;

    // Leyendo el contenido de los archivos
    users = lecturaFile1(f);
    pins = lecturaFile2(f);
    saldos = lecturaFile3(f);

    if(users && pins && saldos) // Verificaci�n de entrar al programa
    {
        while(1)
        {
        printf("----------------------- MENU -----------------------nn");
        printf("Ingrese el numero con la funcion que desea realizarn");
        printf("(1) Iniciar operacionn");
        printf("(2) Cancelar operacionn= ");
        scanf("%d", &menu_input);

        switch(menu_input)
        {
            case 1:
                MenuUserOn = 1;
                saldoEnCuenta = 2000;
                system("clear");

                printf("Ingrese su numero de cuenta.n= ");
                scanf("%d",&number_account);

                while(number_account != 1)
                {
                    system("clear");
                    printf("Opcion invalida, ingrese un nombre de usuario valido.n= ");
                    scanf("%d",&number_account);
                }

                while(MenuUserOn == 1)
                {
                    // Pas� el filtro de seguridad
                    system("clear");
                    printf("----------------------- MENU DE USUARIO -----------------------nn");
                    printf("Clave de usuario: %dn", number_account);
                    printf("Saldo disponible: %dnn", saldoEnCuenta);
                    printf("Ingrese el numero de la opcion que desee consultarn");
                    printf("(1) Depositarn(2) Retirarn(3) Transferirn(4) Cerrar sesionn= ");
                    scanf("%d", &user_input);

                    switch(user_input)
                    {
                        case 1:
                            sleep(1);
                            system("clear");
                            printf("----------------------- DEPOSITAR -----------------------nn");
                            // Futura implementaci�n: Si el saldo es mayor o igual a 10,000. NO DEBE DEPOSITAR
                            sleep(1);
                            break;

                        case 2:
                            sleep(1);
                            system("clear");
                            printf("----------------------- RETIRAR -----------------------nn");
                            // Futura implementaci�n: Si el saldo es menor o igual a 100. NO DEBE RETIRAR
                            sleep(1);
                            break;

                        case 3:
                            sleep(1);
                            system("clear");
                            printf("----------------------- TRANSFERIR -----------------------nn");
                            // Futura implementaci�n: Si el No de cuenta de otro usuario, NO DEBE TRANSFERIR
                            sleep(1);
                            break;

                        case 4:
                            sleep(1);
                            system("clear");
                            sleep(1);
                            printf("----------------------- Sesi�n cerrada exitosamente -----------------------nn");
                            sleep(1);
                            system("clear");
                            MenuUserOn = 0; // Cerrando el menu de consultas en la cuenta
                            break;

                        default:
                            printf("Opcion invalida.nn");
                            break;
                    }
                }
                break;

            case 2:
                sleep(1);
                system("clear");
                sleep(1);
                printf("----------------------- SESION CERRADA EXITOSAMENTE -----------------------n");
                sleep(1);
                return 0;

            default:
                system("clear");
                printf("Opcion no reconocida.nn");
            }
        }
    }
    else
    {
        sleep(1);
        printf("ERROR EN EL SISTEMA, CONTACTE AL TECNICO A CARGO DEL CAJERO");
        sleep(1);
        return 0;
    }
}

/// FUNCIONES DE LECTURA DE ARCHIVOS ////
char** lecturaFile1(struct Archivos file)
{
    file.f1 = fopen("users.txt","r");
    char **users; // Creando buffers de tipo char que apuntar�n hacia
    int n; // Contadores para cada archivo
    char *inicio = NULL; // Punteros para el inicio del archivo
    char *fin = NULL; // Punteros para el final del archivo
    char *linea = NULL;
    char *bufferAuxiliar; // Buffer que nos permitir� guardar la linea
    int offset; // Desplazamiento del archivo
    int flag; // Variable de estado
    int i, j; // Variables para ciclos

    if(file.f1)
    {
        if(getc(file.f1) != EOF) // SETTINGS PARA LEER EL ACHIVO
        {
            //PONER EL CURSOR EN INICIO DE CADA ARCHIVO
            fseek(file.f1, 0, SEEK_SET);

            //OBTENER LA DIRECCION DE INICIO
            inicio = file.f1->_ptr;

            //PONER EL CURSOR EN EL FINAL
            fseek(file.f1, 0, SEEK_END);

            //OBTENER LA CANTIDAD DE BYTE DEL ARCHIVO CON FTELL, RESTAR 1 PARA TENER EL OFFSET
            //ENTRE LA DIRECCION DE INICIO Y LA FINAL
            offset = ftell(file.f1) - 1;

            //OBTENER LA DIRECCION FINAL
            fin = file.f1->_ptr + offset;

            //APUNTAR AL INICIO
            fseek(file.f1, 0, SEEK_SET);

            linea = file.f1 -> _ptr;

            //INDICAR QUE TODAVIA NO SE LEE COMPLETAMENTE EL ARCHIVO
            flag = LECTURA_INCOMPLETA;
        }

        if(linea)
        {
            /// APERTURA DE LECTURA DE INFORMACI�N PARA EL ARCHIVO USERS
            users = calloc(5, sizeof(char*)); // Creando espacio para los usuarios
            flag = LECTURA_INCOMPLETA; // Asignando la bandera a 0
            i = 0; // Rastrear el valor del buffer main
            while(1)
            {
                // Apuntar al primer char
                linea = file.f1 -> _ptr;
                n = 0; // Definiendo el valor de estos en 0

                //CONTAR HASTA QUE ENCUENTRE UN SALTO DE LINEA, FIN DE LINEA, O QUE YA ENCONTR� EL ULTIMO CARACATER DEL ARCHIVO
                while(linea[n] != 'n' && linea[n] != '' && (linea+n+1) != fin)
                {
                    n++;
                }
                n+=1;

                bufferAuxiliar = calloc(n, sizeof(char));
                users[i] = calloc(n, sizeof(char)); // Creando espacio en la posici�n i con n longitud de chars

                //COPIAR CARACTER POR CARACTER con FGETC, SE PODRIA USAR FGETS
                for(j = 0; j < n; j++)
                {
                    bufferAuxiliar[j] = fgetc(file.f1);
                    users[i][j] = bufferAuxiliar[j]; // Copiando cada char de bufferAuxiliar en Base de datos

                    //CAMBIAR SALTO DE LINEA POR CARACATER VACIO PARA IMPRESION
                    if(bufferAuxiliar[j]=='n')
                    {
                        bufferAuxiliar[j] = '';
                    }
                    if(bufferAuxiliar[j] == EOF)
                    {
                        //INDICAR QUE YA SE LLEGO AL FINAL DEL ARCHIVO
                        flag = LECTURA_COMPLETA;

                        //SUSTITUIR EOF POR CARACTER VACIO PARA IMPRESION
                        bufferAuxiliar[j] = '';
                    }
                }
                i++; // Limpiando archivo
                free(bufferAuxiliar); // Limpiando buffer auxiliar

                //TERMINAR DE LEER LINEAS EN EL ARCHIVO
                if(flag == LECTURA_COMPLETA)
                {
                    return users; // Retorno de la informaci�n
                }
            }
        }
        else
        {
            return 0; // fail
        }
    }
    else
    {
        return 0; // fail
    }
}

char** lecturaFile2(struct Archivos file)
{
    file.f2 = fopen("pins.txt","r");
    char **pins; // Creando buffers de tipo char que apuntar�n hacia
    int n; // Contadores para cada archivo
    char *inicio = NULL; // Punteros para el inicio del archivo
    char *fin = NULL; // Punteros para el final del archivo
    char *linea = NULL;
    char *bufferAuxiliar; // Buffer que nos permitir� guardar la linea
    int offset; // Desplazamiento del archivo
    int flag; // Variable de estado
    int i, j; // Variables para ciclos

    if(file.f2)
    {
        if(getc(file.f2) != EOF) // SETTINGS PARA LEER EL ACHIVO
        {
            //PONER EL CURSOR EN INICIO DE CADA ARCHIVO
            fseek(file.f2, 0, SEEK_SET);

            //OBTENER LA DIRECCION DE INICIO
            inicio = file.f2->_ptr;

            //PONER EL CURSOR EN EL FINAL
            fseek(file.f2, 0, SEEK_END);

            //OBTENER LA CANTIDAD DE BYTE DEL ARCHIVO CON FTELL, RESTAR 1 PARA TENER EL OFFSET
            //ENTRE LA DIRECCION DE INICIO Y LA FINAL
            offset = ftell(file.f2) - 1;

            //OBTENER LA DIRECCION FINAL
            fin = file.f2 -> _ptr+offset;

            //APUNTAR AL INICIO
            fseek(file.f2, 0, SEEK_SET);

            linea = file.f2 -> _ptr;

            //INDICAR QUE TODAVIA NO SE LEE COMPLETAMENTE EL ARCHIVO
            flag = LECTURA_INCOMPLETA;
        }

        if(linea)
        {
            /// APERTURA DE LECTURA DE INFORMACI�N PARA EL ARCHIVO PINS
            pins = calloc(5, sizeof(char*)); // Creando espacio para los usuarios
            flag = LECTURA_INCOMPLETA; // Asignando la bandera a 0
            i = 0; // Rastrear el valor del buffer main
            while(1)
            {
                // Apuntar al primer char
                linea = file.f2 -> _ptr;
                n = 0; // Definiendo el valor de estos en 0

                //CONTAR HASTA QUE ENCUENTRE UN SALTO DE LINEA, FIN DE LINEA, O QUE YA ENCONTR� EL ULTIMO CARACATER DEL ARCHIVO
                while(linea[n] != 'n' && linea[n] != '' && (linea+n+1) != fin)
                {
                    n++;
                }
                n+=1;

                bufferAuxiliar = calloc(n, sizeof(char));
                pins[i] = calloc(n, sizeof(char)); // Creando espacio en la posici�n i con n longitud de chars

                //COPIAR CARACTER POR CARACTER con FGETC, SE PODRIA USAR FGETS
                for(j = 0; j < n; j++)
                {
                    bufferAuxiliar[j] = fgetc(file.f2);
                    pins[i][j] = bufferAuxiliar[j]; // Copiando cada char de bufferAuxiliar en Base de datos

                    //CAMBIAR SALTO DE LINEA POR CARACATER VACIO PARA IMPRESION
                    if(bufferAuxiliar[j]=='n')
                    {
                        bufferAuxiliar[j] = '';
                    }
                    if(bufferAuxiliar[j] == EOF)
                    {
                        //INDICAR QUE YA SE LLEGO AL FINAL DEL ARCHIVO
                        flag = LECTURA_COMPLETA;

                        //SUSTITUIR EOF POR CARACTER VACIO PARA IMPRESION
                        bufferAuxiliar[j] = '';
                    }
                }
                i++; // Limpiando archivo
                free(bufferAuxiliar); // Limpiando buffer auxiliar

                //TERMINAR DE LEER LINEAS EN EL ARCHIVO
                if(flag == LECTURA_COMPLETA)
                {
                    return pins; // Retorno de la informaci�n
                }
            }
        }
        else
        {
            return 0; // fail
        }
    }
    else
    {
        printf("Archivo no encontradon");
        return 0; // fail
    }
}

char** lecturaFile3(struct Archivos file)
{
    file.f3 = fopen("saldos.txt","r");
    char **saldos; // Creando buffers de tipo char que apuntar�n hacia
    int n; // Contadores para cada archivo
    char *inicio = NULL; // Punteros para el inicio del archivo
    char *fin = NULL; // Punteros para el final del archivo
    char *linea = NULL;
    char *bufferAuxiliar; // Buffer que nos permitir� guardar la linea
    int offset; // Desplazamiento del archivo
    int flag; // Variable de estado
    int i, j; // Variables para ciclos

    if(file.f3)
    {
        if(getc(file.f3) != EOF) // SETTINGS PARA LEER EL ACHIVO
        {
            //PONER EL CURSOR EN INICIO DE CADA ARCHIVO
            fseek(file.f3, 0, SEEK_SET);

            //OBTENER LA DIRECCION DE INICIO
            inicio = file.f3 -> _ptr;

            //PONER EL CURSOR EN EL FINAL
            fseek(file.f3, 0, SEEK_END);

            //OBTENER LA CANTIDAD DE BYTE DEL ARCHIVO CON FTELL, RESTAR 1 PARA TENER EL OFFSET
            //ENTRE LA DIRECCION DE INICIO Y LA FINAL
            offset = ftell(file.f3) - 1;

            //OBTENER LA DIRECCION FINAL
            fin = file.f3 -> _ptr+offset;

            //APUNTAR AL INICIO
            fseek(file.f3, 0, SEEK_SET);

            linea = file.f3 -> _ptr;

            //INDICAR QUE TODAVIA NO SE LEE COMPLETAMENTE EL ARCHIVO
            flag = LECTURA_INCOMPLETA;
        }

        if(linea)
        {
            /// APERTURA DE LECTURA DE INFORMACI�N PARA EL ARCHIVO SALDOS
            saldos = calloc(5, sizeof(char*)); // Creando espacio para los usuarios
            flag = LECTURA_INCOMPLETA; // Asignando la bandera a 0
            i = 0; // Rastrear el valor del buffer main
            while(1)
            {
                // Apuntar al primer char
                linea = file.f3 -> _ptr;
                n = 0; // Definiendo el valor de estos en 0

                //CONTAR HASTA QUE ENCUENTRE UN SALTO DE LINEA, FIN DE LINEA, O QUE YA ENCONTR� EL ULTIMO CARACATER DEL ARCHIVO
                while(linea[n] != 'n' && linea[n] != '' && (linea+n+1) != fin)
                {
                    n++;
                }
                n+=1;

                bufferAuxiliar = calloc(n, sizeof(char));
                saldos[i] = calloc(n, sizeof(char)); // Creando espacio en la posici�n i con n longitud de chars

                //COPIAR CARACTER POR CARACTER con FGETC, SE PODRIA USAR FGETS
                for(j = 0; j < n; j++)
                {
                    bufferAuxiliar[j] = fgetc(file.f3);
                    saldos[i][j] = bufferAuxiliar[j]; // Copiando cada char de bufferAuxiliar en Base de datos

                    //CAMBIAR SALTO DE LINEA POR CARACATER VACIO PARA IMPRESION
                    if(bufferAuxiliar[j]=='n')
                    {
                        bufferAuxiliar[j] = '';
                    }
                    if(bufferAuxiliar[j] == EOF)
                    {
                        //INDICAR QUE YA SE LLEGO AL FINAL DEL ARCHIVO
                        flag = LECTURA_COMPLETA;

                        //SUSTITUIR EOF POR CARACTER VACIO PARA IMPRESION
                        bufferAuxiliar[j] = '';
                    }
                }
                i++; // Limpiando archivo
                free(bufferAuxiliar); // Limpiando buffer auxiliar

                //TERMINAR DE LEER LINEAS EN EL ARCHIVO
                if(flag == LECTURA_COMPLETA)
                {
                    return saldos; // Retorno de la informaci�n
                }
            }
        }
        else
        {
            return 0; // fail
        }
    }
    else
    {
        return 0; // fail
    }
}

I hope y’all guys can help me, I would appreciate a lot.

I tried to use the command -l and -L on the Makefile line where the error appears in terminal.
Example:

C_SOURCE = main.c
main.o: $(C_SOURCE)
    gcc -L stdio. h-c $(C_SOURCE)

2

Answers


  1. FILE is an opaque type: this means you cannot portably dereference the FILE * and access its members. The structure contents is not documented so there is no point trying to access file.f1 -> _ptr.

    The code is bogus: it uses hard coded knowledge of the FILE implementation and assumes the file fits in the FILE buffer. Don’t use this code even on the platform it was written for.

    After you determine the file length, You can read the file contents with fread and set a null terminator. Alternately, you can read one line at a time woth fgets()

    Login or Signup to reply.
  2. I’m trying yo compile a C file which I have a section to read info from a file ‘users.txt’ using the _ptr pointer from the FILE structure.

    The ISO C Standard does that specify whether FILE has a _ptr member. The code you’re writing is incredibly non-portable, you should never be peeking into FILE‘s internals.

    If you want to read data from a file, use fgets()/fscanf()/fread().

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search