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
FILE
is an opaque type: this means you cannot portably dereference theFILE *
and access its members. The structure contents is not documented so there is no point trying to accessfile.f1 -> _ptr
.The code is bogus: it uses hard coded knowledge of the
FILE
implementation and assumes the file fits in theFILE
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 wothfgets()
…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 intoFILE
‘s internals.If you want to read data from a file, use
fgets()
/fscanf()
/fread()
.