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
}
}
}
}
}
}
Related
I'm having problems while reading a file -again.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct camion {
int data[3];
int numeropacchi;
char *hubprovenienza[100];
_Bool iseccezionale;
};
int main(void) {
struct camion **listacamion = malloc(sizeof(struct camion * ));
listacamion[0] = calloc(1, sizeof(struct camion));
int numerocamion = 0;
//importazione
FILE *input = fopen("info.txt", "r");
if (input != NULL) {
char *temp = calloc(100, sizeof(char));
for (int i = 0; true; i++) {
//1, 2, 3
fscanf(input, "%d - %d - %d",
&listacamion[i]->data[0],
&listacamion[i]->data[1],
&listacamion[i]->data[2]);
printf("ORA %d-%d-%d\n",
listacamion[i]->data[0],
listacamion[i]->data[1],
listacamion[i]->data[2]);
fscanf(input, "%d", &listacamion[i]->numeropacchi);
printf("NUMERO PACCHI %d\n", listacamion[i]->numeropacchi);
if (fscanf(input, "%s", listacamion[i]->hubprovenienza) == EOF) {
listacamion[i]->iseccezionale = false;
break;
}
printf("HUB PROVENIENZA %s\n", listacamion[i]->hubprovenienza);
//4
char eccezionale;
long i_senoneccezionale = ftell(input);
if (fscanf(input, "%s", temp) == EOF)
break;
else { //if not EOF alloc mem for the next truck
listacamion = realloc(listacamion, sizeof(struct camion *) * (i + 1));
listacamion[i + 1] = calloc(1, sizeof(struct camion))
numerocamion++;
printf("RIALLOCATA!\n");
}
if (temp[0] == 'E') //if 'E' is there, bool is true
listacamion[i]->iseccezionale = true;
else {
//otherwise go back to the saved pointer
listacamion[i]->iseccezionale = false;
fseek(input, i_senoneccezionale, SEEK_SET);
}
//set temp to zero;
free(temp);
temp = calloc(100, sizeof(char));
//---
printf("YES OR NO %d\n\n", listacamion[i]->iseccezionale);
}
}
//---
return 0;
}
Here's the input file I use:
22 - 03 - 2020
39
Bergamo
E
30 - 05 - 2021
90
Napoli
19 - 02 - 2022
132
Bari
21 - 03 - 2022
1721
Modena
E
I've got 3 or 4 lines per camion (truck) in my file, depending on whether the load is oversized or not (if it is, then an 'E' is put, otherwise the line in the file doesn't exist). So the end of the file could be detected either at the third fscanf or the fourth, but I'm not sure fscanf works this way... The issue is that the loop is correctly executed 3 times out of 4 (I've got the info of 4 trucks), then I get a segmentation fault, so I assumed that the problem might be an inadequate detection of the end of the file. I've tried other options - feof for example - but they weren't useful, and I can only find examples of a fscanf used as a condition, while my condition is just a true because I have different fscanfs...
Here's my output:
ORA 22-3-2020
NUMERO PACCHI 39
HUB PROVENIENZA Bergamo
RIALLOCATA!
YES OR NO 1
ORA 30-5-2021
NUMERO PACCHI 90
HUB PROVENIENZA Napoli
RIALLOCATA!
YES OR NO 0
ORA 19-2-2022
NUMERO PACCHI 132
HUB PROVENIENZA Bari
RIALLOCATA!
--------------------------------
Process exited after 0.4117 seconds with return value 3221226356
You should test the return value of every call to fscanf(): fscanf returns the number of successful conversions. A return value different from the number of conversions requested is an indication of invalid or missing input. Both must be handled to avoid undefined behavior.
fscanf(input, "%s", temp) is risky: a word longer than 99 bytes will cause a buffer overflow. You should write fscanf(input, "%99s", temp)
Here is a modified version using an array of structures instead of an array of pointers:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct camion {
int data[3];
int numeropacchi;
char *hubprovenienza[100];
_Bool iseccezionale;
};
int main() {
struct camion *listacamion = NULL;
struct camion cam;
char ebuf[2];
int numerocamion = 0;
//importazione
FILE *input = fopen("info.txt", "r");
if (input != NULL) {
while (fscanf(input, "%d - %d - %d\n%d\n%99s",
&cam.data[0], &cam.data[1], &cam.data[2],
&cam.numeropacchi,
cam.hubprovenienza) == 5) {
cam.iseccezionale = false;
if (fscanf(input, " %1[E]", ebuf) == 1)
cam.iseccezionale = true;
printf("ORA %d-%d-%d\n"
"NUMERO PACCHI %d\n"
"HUB PROVENIENZA %s\n"
"YES OR NO %d\n\n",
cam.data[0], cam.data[1], cam.data[2]);
cam.numeropacchi,
cam.hubprovenienza,
cam.iseccezionale);
// if new truck, append to array
listacamion = realloc(listacamion, sizeof(*listacamion) * (numerocamion + 1));
listacamion[numerocamion] = cam;
numerocamion++;
printf("RIALLOCATA!\n");
}
}
return 0;
}
Check the return value of every call to scanf. You can refactor your code to make it simpler. Try something like:
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
struct camion {
int data[3];
int numeropacchi;
char hubprovenienza[100];
_Bool iseccezionale;
};
int
get_record(FILE *fp, struct camion *c)
{
/* Read up to one record from the file. Return 1 on success. */
if( 3 != fscanf(fp, "%d -%d -%d", c->data, c->data + 1, c->data + 2) ){
return 0;
}
if( 1 != fscanf(fp, "%d", &c->numeropacchi) ){
return 0;
}
if( 1 != fscanf(fp, "%99s", c->hubprovenienza) ){
return 0;
}
int k;
while( ( k = fgetc(fp)) != EOF && isspace(k) ){
;
}
if( k == 'E' ){
c->iseccezionale = 1;
} else {
c->iseccezionale = 0;
ungetc(k, fp);
}
return 1;
}
int
main(int argc, char **argv)
{
struct camion c;
while( get_record(stdin, &c) ){
printf(
"%s is %soversized\n",
c.hubprovenienza,
c.iseccezionale ? "" : "not "
);
}
return 0;
}
Okay, this morning I've tried again and now it's working. Thanks to your comments I've paid more attention to the fscanf return value; I've also realized that I could get an EOF from either the 1st line per truck or the 4th one, not 3rd and 4th.
I didn't know whether to delete this question or what... so I've decided to post the code that worked for me just in case it might turn useful to some C beginners like me in the future because it contains a couple of things I wish I knew before. I'm also quite sure there's a faster way to do so, but who knows...
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct camion {
int data[3];
int numeropacchi;
char* hubprovenienza[100];
_Bool iseccezionale;
};
int main(void) {
struct camion** listacamion=malloc(sizeof(struct camion*));
listacamion[0]=calloc(1, sizeof(struct camion));
int numerocamion=0;
//importazione
FILE* input=fopen("info.txt", "r");
if(input!=NULL) {
char* temp=calloc(100, sizeof(char));
_Bool primavolta=true;
for(int i=0; true; i++) {
int fs1, fs4;
int temp1, temp2, temp3;
//1
if((fs1=fscanf(input, "%d - %d - %d", &temp1, &temp2, &temp3) == EOF))
break;
else {
numerocamion++;
if(primavolta) {
primavolta=false;
listacamion[i]->data[0]=temp1;
listacamion[i]->data[1]=temp2;
listacamion[i]->data[2]=temp3;
}
else {
//EVENTUALE RIALLOCAZIONE
listacamion=realloc(listacamion, sizeof(struct camion*)*(i+1));
listacamion[i]=calloc(1, sizeof(struct camion));
//---
listacamion[i]->data[0]=temp1;
listacamion[i]->data[1]=temp2;
listacamion[i]->data[2]=temp3;
}
}
//2
fscanf(input, "%d", &listacamion[i]->numeropacchi);
//3
fscanf(input, "%s", listacamion[i]->hubprovenienza);
//4
char eccezionale;
long i_senoneccezionale=ftell(input);
if((fs4=fscanf(input, "%s", temp)) == EOF) {//se è la fine del file...
listacamion[i]->iseccezionale=false;
free(temp);
break;
}
else {
if(temp[0]=='E') //se esiste il carattere 'E' - e quindi la quarta riga ESISTE - assegna il valore positivo alla booleana
listacamion[i]->iseccezionale=true;
else { /*se invece NON esiste il carattere 'E', ripristina il puntatore al file alla stessa riga che avrebbe dovuto contenere la 'E',
così che questo non vada perso per la prossima chiamata a scanf per la prima riga di ciascun camion, quella contenente la data*/
listacamion[i]->iseccezionale=false;
fseek(input, i_senoneccezionale, SEEK_SET);
}
}
//ripristina memoria per temp;
free(temp);
temp=calloc(100, sizeof(char));
//---
}
}
//---
//output
for(int i=0; i<numerocamion; i++) {
printf("%d-%d-%d %d %s %d\n", listacamion[i]->data[0], listacamion[i]->data[1], listacamion[i]->data[2], listacamion[i]->numeropacchi, listacamion[i]->hubprovenienza, listacamion[i]->iseccezionale);
}
return 0;
}
I have got a function to read a file and attribute to a struct array multiple ints and strings, my fscanf format string looks like this: "%d.%d.%d.%d %d %60c%60c%d %8c".
And everything is OK if while I scan it and if I use a printf, but if I don't then the 2 last strings become corrupted at the end.
Since the file is gigantic and that is not the purpose of the function, I would like to take that printf out.
typedef struct
{
int nacional;
int regional;
int distrital;
int municipal;
}id_geo;
typedef struct
{
id_geo id_geo;
long int cartao_cid;
char nome_dono[61];
char morada[61];
int num_porta;
char codigo_postal[9];
}prop_id_dono;
prop_id_dono *ler_ficheiro(char *file_name, int num_linha) {
prop_id_dono *info_geral;
long int cartao_cid;
char nome_ficheiro;
char nome_dono[60];
char morada[60];
int num_porta;
char codigo_postal[8];
int nacional;
int regional;
int distrital;
int municipal;
int i = 0;
FILE *fp;
fp = fopen(file_name, "r");
if (fp == NULL)
printf("Peço desculpa, mas não foi possível abrir o ficheiro.");
info_geral = (prop_id_dono *)malloc(sizeof(prop_id_dono) * num_linhas);
while (fscanf(fp, "%d.%d.%d.%d %ld %60c%60c%d %8c\n",
&nacional, ®ional, &distrital, &municipal,
&cartao_cid, nome_dono, morada, &num_porta, codigo_postal) != EOF) {
// Faz o scan ao ficheiro através de variáveis temporais, sendo que só
// depois é que atribui valores ao vetor que contém a informação geral
info_geral[i].id_geo.nacional = nacional;
info_geral[i].id_geo.regional = regional;
info_geral[i].id_geo.distrital = distrital;
info_geral[i].id_geo.municipal = municipal;
info_geral[i].cartao_cid = cartao_cid;
strcpy(info_geral[i].nome_dono, nome_dono + '\0');
strcpy(info_geral[i].morada, morada + '\0');
info_geral[i].num_porta = num_porta;
strcpy(info_geral[i].codigo_postal, codigo_postal + '\0');
//This is the magical printf
printf("%d.%d.%d.%d %ld %s%s%d %s \n",
info_geral[i].id_geo.nacional, info_geral[i].id_geo.regional,
info_geral[i].id_geo.distrital, info_geral[i].id_geo.municipal,
info_geral[i].cartao_cid, info_geral[i].nome_dono,
info_geral[i].morada, info_geral[i].num_porta,
info_geral[i].codigo_postal);
i++;
}
fclose(fp);
return info_geral;
}
The input is something like this, but it repeats 20,000 something times in the file
1.1.1.1 1234568 Name, 60 caracters in total(including the spaces)Adress(same thing with the spaces here)House Number Postal Code
You parse input fragments with %60c into character arrays of size 60.
Assuming the conversion succeeds, these arrays will not contain proper C strings, and your attempt at concatenating a '\0' does not work in C.
Here are ways to improve your program:
you should read lines into a local array for easier error reporting in case of conversion failures, and use sscanf() fo parsing.
you should make the destination arrays one byte longer and set a null terminator at the end. The arrays in the prop_id_dono structure should be made large enough too.
you should check the return value of sscanf and report conversion failures
you should stop scanning after num_linhas lines.
you should check for memory allocation failure.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int nacional;
int regional;
int distrital;
int municipal;
} id_geo;
typedef struct {
id_geo id_geo;
long int cartao_cid;
char nome_dono[61];
char morada[61];
int num_porta;
char codigo_postal[9];
} prop_id_dono;
prop_id_dono *ler_ficheiro(const char *file_name, int num_linha) {
char buf[256];
prop_id_dono *info_geral;
long int cartao_cid;
char nome_ficheiro;
char nome_dono[61];
char morada[61];
int num_porta;
char codigo_postal[9];
int nacional;
int regional;
int distrital;
int municipal;
int i = 0;
FILE *fp;
fp = fopen(file_name, "r");
if (fp == NULL) {
printf("Peço desculpa, mas não foi possível abrir o ficheiro.");
return NULL;
}
// use calloc to allocate an array initialized to all bits zero
info_geral = (prop_id_dono *)calloc(num_linhas, sizeof(prop_id_dono));
if (info_geral == NULL) {
fclose(fp);
return NULL;
}
while (i < num_linhas && fgets(buf, sizeof buf, fp) != NULL) {
// Faz o scan ao ficheiro através de variáveis temporais, sendo que só
// depois é que atribui valores ao vetor que contém a informação geral
if (sscanf(buf, "%d.%d.%d.%d %ld %60c%60c%d %8c",
&nacional, ®ional, &distrital, &municipal,
&cartao_cid, nome_dono, morada, &num_porta, codigo_postal) != 9) {
printf("parsing error: %s", buf);
continue;
}
info_geral[i].id_geo.nacional = nacional;
info_geral[i].id_geo.regional = regional;
info_geral[i].id_geo.distrital = distrital;
info_geral[i].id_geo.municipal = municipal;
info_geral[i].cartao_cid = cartao_cid;
nome_dono[60] = '\0';
strcpy(info_geral[i].nome_dono, nome_dono);
morada[60] = '\0';
strcpy(info_geral[i].morada, morada);
info_geral[i].num_porta = num_porta;
codigo_postal[8] = '\0';
strcpy(info_geral[i].codigo_postal, codigo_postal);
i++;
}
fclose(fp);
// note that the caller does not receive the number of lines parsed.
// passing the address of a int for this purpose if a good solution.
return info_geral;
}
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 need help :/ this program is supposed to look for a text in a txt file, if this text is there, then generate another text.
for example:
I generate randomly
INSERT INTO ALUM_PROF VALUES (2,4);
And I look in the txt if this text is found, if it is not then I write it in the txt.
Then it generate
INSERT INTO ALUM_PROF VALUES (5,7);
I look for it in the txt, if it is not, I write it in the txt
Then it generate
INSERT INTO ALUM_PROF VALUES (2,4);
I look for it in the txt, as it is in the, then I do not write it and I generate another one again.
int NUMEROS_AL_PROFE();
#define fila 100
int main()
{
char aux[200];
char aux2[200];
int contador=0;
FILE *f;
f = fopen("prueba.txt","a+");
if(f==NULL)
{
printf("no se ha podido abrir el archivo");
exit(1);
}
int i,num_prof,num_alum=1;
num_prof = NUMEROS_AL_PROFE();
fprintf(f,"INSERT INTO ALUM_PROF VALUES (%d,%d);\n",num_alum,num_prof); //escribo en el fichero f
num_alum++;
for(i=0;i<fila;i++)
{
num_prof = NUMEROS_AL_PROFE();
sprintf(aux,"INSERT INTO ALUM_PROF VALUES (%d,%d);\n",num_alum,num_prof); //almaceno el valor en aux
while(!feof(f))
{
fgets(aux2,200,f); //I read from the file f and I keep each line in aux2
if(strcmp(aux,aux2) == 0 ) //If a1 and a2 are equal then it is repeated.
{
contador=1;
}
memset(aux2, '\0',200); //Vacio el array aux2
}
memset(aux, '\0',200);
if(contador==0)
{
fprintf(f,"INSERT INTO ALUM_PROF VALUES (%d,%d);\n",num_alum,num_prof);
}
num_alum++;
}
fclose(f);
}
//Random Number
int NUMEROS_AL_PROFE()
{
int num;
num = rand() % 17 + 1; //Numeros aleatorios entre 1 y 17
num = num + 1;
return num;
}
The program compiles, and when is running it remains loading, it simply does not write anything and generates a heavy txt .
You need to reset the reading position of the file and contador flag.
example of fix code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define fila 100
int NUMEROS_AL_PROFE(void);
int main(void){
char aux[200];
char aux2[200];
int contador=0;
FILE *f = fopen("prueba.txt","a+");
if(f==NULL) {
printf("no se ha podido abrir el archivo");
exit(1);
}
int num_alum = 1;
srand(time(NULL));//Change seed of random number
for(int i = 0; i < fila; i++){
sprintf(aux,"INSERT INTO ALUM_PROF VALUES (%d,%d);\n", num_alum++, NUMEROS_AL_PROFE());
rewind(f);//The file reading position is set to the beginning.
contador = 0;//reset flag
while(fgets(aux2, sizeof aux2, f)){//while(!feof(f)) has a problem. It has already been pointed out by stackptr's comment.
if(strcmp(aux, aux2) == 0 ){
//fprintf(stderr, "DEBUG:already exist %s", aux);
contador = 1;
break;
}
}
if(contador == 0){
//fprintf(stderr, "DEBUG:write %s", aux);
fputs(aux, f);
}
}
fclose(f);
}
int NUMEROS_AL_PROFE(void){
int num;
num = rand() % 17 + 1;
num = num + 1;
return num;
}
i have to input the data into a FILE * (this is in C and using codeblocks), the data is a struct containing 3 char[ ] an 1 double, i dont know why when i print the file it repeats the last struct twice and in "dni" it puts 0.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char dni[9];
char nombre[100], apellido[100];
double monto_adeudado;
} t_datos;
void carga_del_archivo(char[]);
t_datos carga_struct(t_datos);
int main()
{
char nombrearchivo[30];
printf("ingrese el nombre del archivo: ");
gets(nombrearchivo);
carga_del_archivo(nombrearchivo);
return 0;
}
void carga_del_archivo(char nombre[30])
{
FILE* ptrarch;
t_datos aux;
ptrarch = fopen(nombre, "ab");
if (ptrarch != NULL) {
do {
aux = carga_struct(aux);
fwrite(&aux, sizeof(t_datos), 1, ptrarch);
} while (strcmp(aux.dni, "0") != 0);
} else {
printf("ERROR\n");
}
}
t_datos carga_struct(t_datos aux)
{
printf("\ningrese el dni: ");
fflush(stdin);
gets(aux.dni);
if (strcmp(aux.dni, "0") == 0)
return aux;
printf("\ningrese el nombre: ");
fflush(stdin);
gets(aux.nombre);
fflush(stdin);
printf("\ningrese el apellido: ");
gets(aux.apellido);
fflush(stdin);
printf("\ningrese el monto adeudado: ");
scanf("%lf", &aux.monto_adeudado);
return aux;
}
Problem is here:
{
aux=carga_struct(aux);
fwrite(&aux,sizeof(t_datos),1,ptrarch);
}while(strcmp(aux.dni,"0")!=0);
When you enter 0 here aux=carga_struct(aux) you write it to the disk by fwrite on next line before checking this statement: while(strcmp(aux.dni,"0")!=0).