I am writing a simple program that at first checks a file for the number of structures present and allocates memory accordingly, then allows the user to insert new registries and allocates memory for those as well. Before program is terminated, all the data is saved to a binary file. I am able to insert up to 8 "servidor", but no more. When debugging, I found that after 8 entries, the program fails to realloc for a 9th, which indicates memory problems.
Call Stack
ntdll.dll!ntdll!RtlRaiseException (Unknown Source:0)
ntdll.dll!ntdll!RtlIsZeroMemory (Unknown Source:0)
ntdll.dll!ntdll!RtlIsZeroMemory (Unknown Source:0)
ntdll.dll!ntdll!.misaligned_access (Unknown Source:0)
ntdll.dll!ntdll!.misaligned_access (Unknown Source:0)
ntdll.dll!ntdll!.misaligned_access (Unknown Source:0)
ntdll.dll!ntdll!RtlReAllocateHeap (Unknown Source:0)
ntdll.dll!ntdll!RtlReAllocateHeap (Unknown Source:0)
AcLayers.dll!NotifyShims (Unknown Source:0)
msvcrt.dll!realloc (Unknown Source:0)
main() (c:\Users\tiago\Desktop\c.c:145)
Steps to reproduce
Compile
Run
Insert many registries by typing 1 and typing a name.
Program should fail at about 8 insertions, reverting file back to previous saved state, or 0.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
typedef struct Servidor
{
bool ocupado;
int codigo;
char nome[256];
} servidor;
int escrever_arquivo(void * _struct, size_t tam_struct, int tamanho)
{
FILE *fptr = fopen("data.bin", "w");
if(fptr == NULL)
{
return 1;
}
fwrite(_struct, tam_struct * tamanho, 1, fptr);
fclose(fptr);
}
int ler_arquivo(void * _struct, size_t tam_struct, int tamanho)
{
FILE *fptr = fopen("data.bin", "r");
if(fptr == NULL)
{
return 1;
}
fread(_struct, tam_struct * tamanho, 1, fptr);
fclose(fptr);
}
int busca_tamanho()
{
FILE *fptr = fopen("data.bin", "a");
if(fptr == NULL)
{
printf("Erro na abertura do arquivo!\n");
exit(1);
}
fseek(fptr, 0L, SEEK_END);
int tamanho = ftell(fptr);
fclose(fptr);
return tamanho / sizeof(servidor);
}
int busca_livre(servidor * grupo, int tamanho)
{
for(int i = 0; i < tamanho; i++)
{
if(grupo[i].ocupado != true)
{
return i;
}
}
}
void inserir_servidor(servidor * grupo, int tamanho)
{
if(!tamanho)
{
grupo[0].ocupado = true;
grupo[0].codigo = 0;
printf("Nome: ");
fgets(grupo[0].nome, sizeof(grupo[0].nome), stdin);
fflush(stdin);
}
else
{
int pos = busca_livre(grupo, tamanho);
grupo[pos].ocupado = true;
grupo[pos].codigo = pos;
printf("Nome: ");
fgets(grupo[pos].nome, sizeof(grupo[pos].nome), stdin);
fflush(stdin);
}
}
void imprimir_servidor(servidor * grupo, int tamanho)
{
for(int i = 0; i < tamanho; i++)
{
printf("%s %d\n\n", grupo[i].nome, grupo[i].codigo);
}
}
int main()
{
servidor * grupo;
int tamanho = busca_tamanho();
int memoria = tamanho * sizeof(servidor);
if(tamanho)
{
grupo = malloc(memoria);
ler_arquivo(grupo, sizeof(servidor), tamanho);
}
char input;
printf("memoria inicial: %d B , tamanho: %d\n\n", memoria, tamanho);
do
{
printf("1. Inserir servidor\n");
printf("2. Listar servidores\n");
printf("0. Sair do programa\n\n");
printf("> ");
scanf("%c", &input);
fflush(stdin);
switch(input)
{
case '0':
escrever_arquivo(grupo, sizeof(servidor), tamanho);
free(grupo);
printf("Saindo do programa\n");
return 0;
case '1':
if(!tamanho)
{
grupo = malloc(sizeof(servidor));
memoria += sizeof(servidor);
tamanho++;
inserir_servidor(grupo, tamanho);
}
else
{
realloc(grupo, memoria + sizeof(servidor));
memoria += sizeof(servidor);
tamanho++;
inserir_servidor(grupo, tamanho);
}
printf("memoria em uso: %d B , tamanho: %d\n\n", memoria, tamanho);
break;
case '2':
imprimir_servidor(grupo, tamanho);
break;
default:
printf("Inexistente\n");
break;
}
} while(input != '0');
return 0;
}
Related
EDITED
I am trying to write a bidimensional array into a binary file (cop_bin), and I should use fwrite function in the //SAVE ARRAY INTO A BINARY FILE part.
I have used fwrite but it's not working.
As for now I have this code that works perfectly to save data from csv to the array, but now I need to save the array into the binary file.
So far, the code is:
#include<stdio.h>
int muestraMenu ();
void opcion0 (int matriz[699][13]);
int main ()
{
int opcion = 8;
int matriz[699][13];
do
{
opcion = muestraMenu ();
switch (opcion)
{
case 0:
printf (" 0. Configuración e inicialización");
opcion0 (matriz);
break;
case 8:
break;
}
}
while (opcion != 8);
return 0;
}
void opcion0 (int matriz[699][13])
{
int datos[13];
// int matriz[699][13];
int i;
int a[100];
int x = 0;
char line[100];
FILE *f = fopen ("bcancer.csv", "r");
FILE *cop_bin;
if (f == NULL)
{
printf ("error abriendo el fichero bcancer.csv\n");
return;
}
printf ("\n");
//Recorremos fichero para guardar datos en un array bidimensional
while (fgets (line, sizeof line, f))
{
if (sscanf (line, "%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d",
&datos[0], &datos[1], &datos[2], &datos[3], &datos[4],
&datos[5], &datos[6], &datos[7], &datos[8], &datos[9],
&datos[10], &datos[11], &datos[12]) == 13)
{
for (i = 0; i < 13; i++)
{
matriz[x][i] = datos[i];
}
x++;
//datos guardados correctamente
}
else
{
printf ("Datos no válidos");
}
//SAVE ARRAY INTO A BINARY FILE
fwrite(matriz,sizeof(double),1,cop_bin);
fclose(cop_bin);
}
Could you give me a little help?
Thanks a lot.
I'm trying to create a function that given a word in input can find and delete the line that contain it. I've done some research on internet and I wrote some code but when i launch the program only find the line but it doesn't delete the line and the old file (database.txt).
This is the function that deletes the line:
FILE *database, *database2;
char str[500];
int linea = 0, ctr = 0;
char ID[256];
database2 = fopen("database2.txt", "a");
fclose(database2);
database = fopen("database.txt", "r");
if(!database){
printf("Errore nell'apertura del file.\n");
getch();
return;
}
database2 = fopen("database2.txt", "r");
if(!database2){
printf("Errore nell'apertura del file 2.\n");
getch();
return;
}
printf("Inserisci l'ID del libro da eliminare:");
scanf("%s", &ID);
int x = FindLine(ID);
printf("%d", x);
while(!feof(database)){
strcpy(str, "\0");
fgets(str, 256, database);
if(!feof(database)){
ctr++;
if(ctr != x){
fprintf(database2, "%s", str);
}
}
}
fclose(database);
fclose(database2);
remove("database.txt");
rename("database2.txt", "database.txt");
getch();
This is the function that find the line:
FILE *fp;
int line_num = 1;
int find_result = 0;
char temp[512];
fp = fopen("database.txt", "r");
if(fp == NULL){
return(-1);
}
while(fgets(temp, 512, fp) != NULL) {
if((strstr(temp, str)) != NULL) {
return line_num;
find_result++;
}
line_num++;
}
if(find_result == 0) {
printf("\nSorry, couldn't find a match.\n");
}
if(fp) {
fclose(fp);
}
return(0);
Some can help me to find the error please.
Using feof() to check for end of file is incorrect, you should instead check the return value of fgets(). You can learn about this on this question: Why is “while ( !feof (file) )” always wrong? .
Here is a modified version:
#include <stdio.h>
#include <string.h>
int main() {
FILE *database, *database2;
char ID[256];
char str[512];
int linea, ctr;
printf("Inserisci l'ID del libro da eliminare:");
if (scanf("%255s", ID) != 1) {
printf("input error\n");
return 1;
}
database = fopen("database.txt", "r");
if (!database) {
printf("Errore nell'apertura del file database.txt.\n");
return 1;
}
ctr = linea = 0;
while (fgets(str, 512, database)) {
ctr++;
if (strstr(str, ID)) {
linea = ctr;
break;
}
}
if (linea == 0) {
printf("No matching line\n");
fclose(database);
return 1;
}
printf("linea: %d\n", linea);
database2 = fopen("database2.txt", "w");
if (!database2) {
printf("Errore nell'apertura del file database2.txt.\n");
fclose(database);
return 1;
}
rewind(database);
ctr = 0;
while (fgets(str, 512, database)) {
ctr++;
if (ctr != linea) {
fputs(str, database2);
}
}
fclose(database);
fclose(database2);
remove("database.txt");
rename("database2.txt", "database.txt");
return 0;
}
I am having trouble reading from a bin file.
I am recording some text in binary (correctly i think), but my code isn't able to read the text I wrote and print it in the console. When i open the file the information is there (this document is use to storage the information from the client and the login access) and i can login, but when i try to read and print in console it doesn't show me.
I am using a struct to get the values from the document, and then i open the document "fopen()" but when i try to read with the "fread()" in a "while" I don't get in, the print don't give me the right information
I try to reduce as much i could of the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <dir.h>
#include <unistd.h>
#include <time.h>
#include <conio.h>
#define SIZE 1000
typedef struct
{
char id[10];
char nome[100];
char passe[100];
}Pacient;
Pacient p1;
FILE* filepaciente;
//variables
char tmpnome[100], tmppassword[100];
//variable for path
char nomedoc[15];
char pasta[250];
char sessionName[15];
char tmp_name[15];
char fullpath[200];
char tmp_nome[15];
void vedocumento(int* i, char* line, char pacienteData[])
{
// DEFINE A VARIÁVEL USERDATA COMO UMA STRING VAZIA
strcpy(pacienteData, "");
// IF FINDS "|", GO TO THE NEXT CHARACTER
if (line[*i] == '|')
{
(*i)++;
}
//WHEN THE CHARACTER IS DIFERENT THEN |, ADD THAT CHARACTER TO THE ARRAY USERDATA
while (line[*i] != '|') // *i = 0
{
strncat(pacienteData, &line[*i], 1); // userData = "" ; userData = userData + carater
(*i)++;
}
}
findpath()
{
//PROCURA O CAMINHO ONDE SE ENCONTRA O PROJETO
if (getcwd(pasta, sizeof(pasta)) == NULL)
{
printf("ERROR!\n");
}
else
{
strcat(pasta, "\\file\\");
//CRIA O FICHEIRO COM O NUMERO DE INTERNO
strcpy(nomedoc, strcat(tmp_nome, ".bin"));
//JUNTA O CAMINHO COMPLETO AO NOME DO FICHEIRO
strcat(pasta, nomedoc);
strcpy(fullpath, pasta);
}
}
int main() //where i write in the bin file
{
//GETTING REGISTRY DATA
fflush(stdin); //para ir so buscar os dados
printf("\nName pacient: ");
scanf("%[^\n]", p1.nome);
printf("\nPassword do pacient %s: ", p1.nome);
scanf("%s", p1.passe);
printf("\nID pacient %s: ", p1.nome);
scanf(" %s", p1.id);
strcpy(tmp_nome, p1.nome);
strcpy(tmp_nome, strlwr(tmp_nome));
findpath();
if (access(fullpath, F_OK) == 0)
{
//IF EXISTS
printf("Este nome de utilizador já foi registado! Por favor, tente novamente!\n");
}
else
{
// IF DOESN'T EXIST
filepaciente = fopen(fullpath, "wb");
if (filepaciente == NULL)
{
printf("\nerror\n");
}
//size_t elements_written = fwrite(&p1, sizeof(Paciente), 1, filepaciente);
//PRINTING ON FILE
fprintf(filepaciente, "%s|%s|%s\n", p1.nome, p1.passe, p1.id);
fclose(filepaciente);
}
//WHERE I WANT TO PRINT ON THE CONSOLE
{
printf("Name do pacient: ");
scanf(" %[^\n]", tmpnome);
strcpy(tmp_nome, tmpnome);
strcpy(tmp_nome, strlwr(tmp_nome));//this is to get the name of the document
findpath(); //Find the path to the document
if (access(fullpath, F_OK) == 0)
{
filepaciente = fopen(fullpath, "rb"); //Open the document
Pacient pacient[100];
char line[SIZE];
int nline = 0;
fgets(line, SIZE, filepaciente);
int i = 0;
vedocumento(&i, line, pacient[nline].nome);
vedocumento(&i, line, pacient[nline].passe);
nline++;
//LOOP TO CHECK
for (i = 0; i < 1; i++)
{
if (strcmp(tmpnome, pacient[i].nome) == 0)
{ //WRITE INFO
char buf[SIZE];
if (filepaciente == NULL)
{
printf("\nERRO OPENING\n");
}else printf("\nOPEN THE FILE\n");
//IF I PUT "==1" DON'T GET IN THE WHILE
while( fread(&p1, sizeof(p1), 1, filepaciente) == 1)
{
printf("%c", p1); //NOT SURE IF THIS IS CORRECT
}
}
}
}
}
}
When I compile my program with mingw on windows and gcc on linux, the executable file doesn't give me the same result.
This code is supposed to take a file and encrypt it.
But when I need to add some bytes if the last block is not full or if the file is less than 32 bytes, Linux adds the value "0" like I want but on Windows, it doesn't work.
By the way, the hexdump of each isn't similar.
to execute it : ./encrypt [FileIn] [FileOut] 1 [yourKey] [yourIV]
Put anything you want for Key and IV, they are written inside the code for the test(I just put "1" and "1" to don't get an error)
argv[3] needs to be a "1" to encrypt
I'm testing it using a file with "toto" written inside (put anything you want, but be under 32 char because it's what i'm testing for now).
Key and IV are same inside the code to debug, it's not a mistake.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*FUNCTIONS*/
int encrypt(char* in, char* out, char* key, char* primalIv);
int decrypt(char* in, char* out);
void myprint(char* content, int size);
char* xor(char* data, char* key, int size);
void bitStuffing(char* in, int rem);
/*GLOBAL VARIABLES*/
int errorLevel;
int blockSize = 32; /*Tailles de blocs en octet*/
/*CALL : ./main inFile outFile methode key iv*/
/*FILE STRUC : [datas] [stuffing] [stuffingValue] [iv]*/
int main(int argc, char** argv)
{
/*Support de l'aide à l'utilisateur*/
if(argc == 2 && !strcmp(argv[1],"help"))
{
printf("\nUsage : ./cied [inFile] [outFile] [methode] [key] [iv]\n\n");
printf("[inFile] : Input file to use\n");
printf("[outFile] : Ouput file to use\n");
printf("[methode] : Encrypt (1) or decrypt (0)\n");
printf("[key] : The key to use\n");
printf("[iv] : The initialisation vector.\n");
printf(" (none for decrypt !)\n");
return 0; /*Fermeture gratieuse du programme*/
}
/*Support des erreurs d'arguments*/
if(argc != 5 && argc != 6)
{
printf("[ERR] Args error!\n");
printf("[INF] Enter 'help' to display help\n");
return 1;
}
else if(atoi(argv[3]) == 1 && argc != 6) /*Nombre d'arguments pour chiffrement*/
{
printf("[ERR] Args error : given %d when waiting 5!\n",(argc-1));
printf("[INF] Enter 'help' to display help\n");
return 1;
}
else if(atoi(argv[3]) == 0 && argc != 5)/*Nombre d'arguments pour dechiffrement*/
{
printf("[ERR] Args error : given %d when waiting 4!\n",(argc-1));
printf("[INF] Enter 'help' to display help\n");
return 1;
}
/***Chiffrement et dechiffremet***/
if(atoi(argv[3]) == 1)
{
errorLevel = encrypt(argv[1], argv[2],"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");/*Chiffrement*/
if(!errorLevel)
{
printf("[INF] finished\n");
}
else
{
printf("[ERR] An error as occured.\n");
}
}
else if(atoi(argv[3]) == 0)
{
errorLevel = decrypt(argv[1], argv[2]); /*Dechiffrement*/
if(!errorLevel)
{
printf("[INF] finished\n");
}
else
{
printf("[ERR] An error as occured.\n");
}
}
else
{
printf("[ERR] Wrong method given!");
printf("[INF] Enter 'help' to display help\n");
return 1;
}
return 0;
}
/*FONCTIONS CORE*/
int encrypt(char* in, char* out, char* key, char* primalIv)
{
/*Variables*/
char* block = NULL;
char* xored = NULL;
char* iv = NULL;
int readed;
int inFileSize;
int numOfBlock;
int rem = 0;
int i;
FILE *inFile;
FILE *outFile;
iv = primalIv;
/*Ouverture des fichiers*/
inFile = fopen(in,"rb");
outFile = fopen(out,"w");
/*Gestion des erreurs de fichier*/
if(inFile == NULL)
{
printf("[ERR] Problem reading input file. Please check path and permissions.\n");
}
else if(outFile == NULL)
{
printf("[ERR] Problem reading output file. Please check path and permissions.\n");
}
block = malloc(blockSize);
/*Récupération de la longueur du fichier*/
fseek(inFile, 0, SEEK_END);
inFileSize = ftell(inFile);
rewind(inFile);
/*Calcul du nombre de bloc et du reste*/
numOfBlock = inFileSize / blockSize;
rem = inFileSize % blockSize;
printf("[INF] File will be split in %d block(s). %d will remain.\n",numOfBlock,rem);
if(inFileSize < blockSize)
{
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
/*Bourrage*/
bitStuffing(block,(blockSize-readed));
/*Xor avec l'IV*/
xored = xor(block,iv,blockSize);
/*Xor avec la clé*/
xored = xor(xored,key,blockSize);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,blockSize,outFile);
}
else
{
for(i=0;i<numOfBlock;i++)
{
printf("qzekonfk le\n");
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
if(readed != blockSize)
{
printf("[WRN] The readed block siez is different than usual !(%d != %d)\n",blockSize,readed);
}
/*Xor avec l'IV*/
printf("IV :\n");
xored = xor(block,iv,readed);
/*Xor avec la clé*/
printf("KEY :\n");
xored = xor(xored,key,readed);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,readed,outFile);
}
/*Bourrage*/
if(rem)
{
readed = fread(block,1,blockSize,inFile);
printf("[INF] readed %d bytes \n",readed);
/*Bourrage*/
bitStuffing(block,(blockSize-readed));
/*Xor avec l'IV*/
xored = xor(block,iv,readed);
/*Xor avec la clé*/
xored = xor(xored,key,readed);
/*Sauvegarde du block pour réutilisation en tant qu'IV*/
iv = xored;
/*Ecriture dans le fichier*/
fwrite(xored,1,readed,outFile);
}
}
/*Inscription de rem dans le fichier pour préparer le déchiffrement*/
fprintf(outFile, "%c",rem);
/*Inscription de l'IV*/
printf("IV (again):\n");
fwrite(xor(primalIv,key,blockSize),1,blockSize,outFile);
/*Free des malloc*/
free(block);
free(xored);
return 0;
}
int decrypt(char* in, char* out)
{
return 0;
}
/*FONCTIONS UTILITAIRES*/
char* xor(char* data, char* key, int size)
{
int i;
char* result = malloc(size);
for(i=0; i<size; i++)
{
result[i] = data[i] ^ key[i];
printf(" %x ^ %x = %x\n",data[i],key[i],result[i]);
}
return result;
}
void myprint(char* content, int size)
{
int i;
printf(" ");
for(i=0;i<=blockSize;i++)
{
printf(" %x",content[i]);
}
printf("\n");
}
void bitStuffing(char* in, int rem) {
int i;
printf("\nBEGIN STUFFING");
for(i=rem; i<sizeBlock; i++) {
in[i] = 0;
/*printf("%x", in[i]);*/
}
printf("\nEND STUFFING\n");
}
#alk You're true, i found it just before reading your post.
My friend give a wrong value to the bitStuffing() function. He don't need to give the number of empty bytes, but the byte where the loop have to begin. Then it will be
bitStuffing(block, readed);
and not
bitStuffing(block, (blockSize-readed));
For everyone who want a little less code, i create this to have essentially the stuffing :
#include <stdio.h>
#include <stdlib.h>
void bitStuffing(char* in, int rem);
void myprint(char* content, int size);
int blockSize = 32;
int main()
{
char* block;
int inFileSize = 4; /*In my example, the file used is a text file containing "toto"*/
int readed;
FILE *outFile;
readed = inFileSize % blockSize; /*Getting the number of bits to stuff*/
block = malloc(blockSize);
block[0] = "t";
block[1] = "o";
block[2] = "t";
block[3] = "o";
bitStuffing(block, readed);
outFile = fopen("C:/Users/Julien/Desktop/text3.txt", "wb");
fwrite(block,1,blockSize,outFile);
fclose(outFile);
return 0;
}
void bitStuffing(char* in, int begin) {
printf("\nBEGIN STUFFING");
printf("\nrem =%2d", begin);
int i;
for(i=begin; i<blockSize; i++) {
in[i] = 0;
printf("\ni =%1d | value =%1x\n ",i, in[i]);
myprint(in, i);
}
printf("\nEND STUFFING\n");
}
void myprint(char* content, int size)
{
int i;
printf("\n");
for(i=0;i<size;i++)
{
printf("%2x",content[i]);
}
printf("\n");
}
This works as well like i want. Then i was sure that the problem didn't come from the bitStuffing
Thank's everybody
Now, i will slap my friend
I have a program that I am trying to write that will open a file named list.txt, this file will contain a num, a ID, and a string name on each line. This program will read list.txt file and sort ID numbers and print sorted ID with number and name to index.txt file. I wrote a program code and it's working...
Here is my list.txt
(num, ID, name)
0 3 AB
1 2 BC
2 28 DC
3 1 EF
4 13 BB
10 30 CC
11 23 FF
14 16 GG
After compiled this program sorted ID with number and name, print to index.txt and it should be:
(ID, num, name)
1 3 EF
2 1 BC
3 0 AB
13 4 BB
16 14 GG
23 11 FF
28 2 DC
30 10 CC
Here is my program code:
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include <stdlib.h>
#include <string.h>
#define NUM_NUMBERS 9
typedef struct student
{
int num;
int id;
char name[100];
}end;
void update();
void Sort(student array[], int n);
void load_menu();
void add(end *e);
void search(end e);
void view(end e);
FILE *fp;
FILE *f1;
int main(int argc, char** argv)
{
load_menu();
return 0;
}
void update()
{
end st[15];
int sayi[NUM_NUMBERS], number, i=0, j=0;
fp=fopen("list.txt", "r");
if( fp == NULL )
{
printf("File is not found at add();\n");
exit(0);
}
while(!feof(fp))
{
fscanf(fp,"%d%d%s",&st[i].num,&st[i].id,st[i].name);
i++;
}
Sort(st, NUM_NUMBERS);
f1=fopen("index.txt", "w");
for(int i=0; i<NUM_NUMBERS;i++)
{
fprintf(f1, "%d %d %s\n", st[i].id, st[i].num, st[i].name);
}
}
void Sort(end array[], int n)
{
int Min;
for(int i=0; i<n-1;i++)
{
Min=i;
for(int j=i+1;j<n;j++)
{
if(array[j].id<array[Min].id)
{
Min=j;
}
}
end temp=array[i];
array[i]=array[Min];
array[Min]=temp;
}
}
void load_menu(void)
{
end e;
int choice;
do
{
printf("1. Find a record given its ID value \n");
printf("2. Add a new record to the file \n");
printf("3. View Records\n");
printf("4. Exit\n\n");
printf("Please choose one: ");
scanf("%d",&choice);
switch(choice)
{
case 1:
search(e);
break;
case 2: add(&e);
update();
break;
case 3: view(e);
break;
case 4: printf("Done.");
return;
break;
default: printf("Invalid choice\n");
}
}while (choice != 5);
system("cls");
}
void add(end *e)
{
int i=0;
system("cls");
fp = fopen ( "list.txt", "a" );
if( fp == NULL )
{
printf("File is not found at add();\n");
exit(0);
}
printf("\n-----Add a new record-----\n");
printf("Enter number: ");
scanf("%d", &e->num);
printf("\nEnter ID : ");
scanf("%d",&e->id);
printf("\nEnter name: ");
scanf("%s",e->name);
fscanf(fp,"%d %d %s\n\n",&e->num, &e->id, e->name);
fprintf(fp,"%d %d %s\n\n",e->num ,e->id, e->name);
fclose(fp);
return;
}
void search(end e)
{
int i=0;
int sid;
system("cls");
fp = fopen ("list.txt", "r");
if(fp==NULL)
{
printf("File is not found at search();");
}
printf("\n-----Search ID-----\n");
printf("\nEnter ID : ");
scanf("%d",&sid);
printf("\nNumber ID Name");
while(!feof(fp))
{
fscanf(fp,"%d %d %s", &e.num, &e.id, &e.name);
if(sid==e.id)
{
printf("\n%d %d %s",e.num ,e.id, e.name);
}
}
printf("\n\n");
fclose(fp);
}
void view(end e)
{
int i=0;
system("cls");
printf("\n-----list.txt-----\n");
fp = fopen("list.txt", "r");
if(fp == NULL)
{
printf("File is not found at view();\n");
exit(0);
}
printf("\nNumber ID Name");
printf("\n");
while(fscanf (fp, "%d %d %s ",&e.num, &e.id, &e.name) != EOF )
printf("\n%d %d %s",e.num ,e.id, e.name);
printf("\n\n");
printf("-----index.txt-----\n");
f1 = fopen("index.txt", "r");
if(fp == NULL)
{
printf("File is not found.\n");
exit(0);
}
printf("\nNumber ID Name");
printf("\n");
while(fscanf (f1, "%d %d %s ",&e.id, &e.num, &e.name) != EOF )
printf("\n%d %d %s",e.id ,e.num, e.name);
printf("\n\n");
fclose(fp);
fclose(f1);
return;
}
But I used only array so I need to dynamically allocate at array of struct to store the info. Still don't know how to use dynamically allocate (malloc). Could you please show me how to use dynamically with code? Thanks for helps. (Sorry for bad english.)
sample code:
#include <stdio.h>
#include <stdlib.h>
typedef struct student{
int num;
int id;
char name[100];
}end;
int cmp(void const *a, void const *b){
const end *x = a;
const end *y = b;
return x->id < y->id ? -1 : x->id > y->id;
}
int main(void){
end *st = NULL, tmp;
FILE *fp;
size_t i = 0, n = 0;
fp=fopen("list.txt", "r");
if( fp == NULL ) {
perror("fopen at XXX");
exit(EXIT_FAILURE);
}
while(3 == fscanf(fp,"%d %d %s", &tmp.num, &tmp.id, tmp.name)){
end *temp = realloc(st, ++n * sizeof(*st));//Secure multiple records when the number of records is large
if(temp == NULL){
perror("realloc at XXX");
free(st);
exit(EXIT_FAILURE);
}
st = temp;
st[i++] = tmp;
}
fclose(fp);
qsort(st, n, sizeof(*st), cmp);
fp=fopen("index.txt", "w");
for(i = 0; i < n; ++i){
fprintf(fp, "%d %d %s\n", st[i].id, st[i].num, st[i].name);
}
fclose(fp);
free(st);
}
malloc() returns a pointer to the memory you allocated. The argument is the size of the memory you want to allocate, so in your case its the size of of "end".
You need to declare a pointer to "end" first and then call malloc().
end * ptr = malloc(sizeof(end));
But thats just one Element. You should definitely check out a tutorial for lists in c.