to search and write in txt file C - c

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;
}

Related

Multiple fscanf statements in a loop. How do I get when EOF is reached?

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;
}

Write bidimensional array into a binary file

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.

Reading from binary file LANG C

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
}
}
}
}
}
}

C Program don't have the same result when compiled on linux and windows

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

free(): invalid next size(normal)

When running this code with an input .txt file containing somewhere between 200-300 integers (separated by spaces) i get an error right before the for loop with the fprintf statement.
I am not sure if qsort is causing this error or why it occurs but any insight would be appreciated.
(this file is run by adding the name of the input file and the output file in the command line ex: ./program input.txt output.txt
My code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main(int argc, char *argv[]){
if(argc != 3){
printf("\nInvalid input\nPlease provide the input and output text file names as %s name1 name2\n", argv[0]);
}else{
printf("\nPart A: \n");
printf("..............................................................................................................\n\n");
char *fn1 = argv[1]; //variables
char *fn2 = argv[2];
int temp = 0;
int counter = 0;
int index = 0;
int index2 = 0;
int sort = 0;
FILE *fp1 = fopen(fn1, "r"); //read file
FILE *fp2 = fopen(fn2, "w"); //write file
if(fp1 == NULL){ //test if fp1 was opened
printf("There was an error opening the input file");
}
char data[10]; //ints can only hold 10 digits
int *integerArr;
int *tempPointer;
integerArr = malloc(10*sizeof(int));
int sizeOfArrs = 10;
printf("Reading in the textfile: ");
while(fscanf(fp1,"%s",data) != EOF){ //reads in the file breaking on each whitespace and ends at the EOF pointer
temp = strlen(data);
if(temp <=10){
temp = atoi(data);
integerArr[counter] = temp;
printf(".");
counter++;
if(counter == sizeOfArrs -1){
temp = sizeOfArrs * 2;
tempPointer = realloc(integerArr, temp);
if(tempPointer != NULL){
integerArr = tempPointer;
}
}
}else printf("\ninteger had too many digits\n");
}
printf(" Done\n%d Numbers were found\n", counter);
printf("The integers found in the %s file: \n", argv[1]);
index = 0; //reset index to 0;
for(index;index<counter;index++){ //prints the unsorted contents of the file
printf("%d ", integerArr[index]);
}
printf("\n\nPart B\n");
printf("..............................................................................................................\n\n");
printf("The integers found in the %s file after sorting: \n", argv[1]);
qsort(integerArr, counter, sizeof(int), cmpfunc); //best function ever (sorts the array using the cmpfunc to tell if an integer is greater than less than or equal to the next one)
index = 0; //resets the index
for(index; index <counter; index++){ //prints the sorted contents of the file
printf("%d ", integerArr[index]);
fprintf(fp2,"%d ",integerArr[index]); //writes the sorted integers to the new file
}
if(fp2 == NULL){ //tests if the write worked
printf("There was an error writing the outputfile");
}
printf("\n");
close(fp1,fp2); //closes both files
}
return 0;
}
Your fscanf loop is broken. You weren't actually realloc'ing with a larger size. Here's the corrected program [sorry for the pedantic style reedit but you hit one of my nits: long sidebar comments]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int
cmpfunc(const void *a, const void *b)
{
return (*(int *) a - *(int *) b);
}
int
main(int argc, char *argv[])
{
if (argc != 3) {
printf("\nInvalid input\nPlease provide the input and output text file names as %s name1 name2\n", argv[0]);
return 1;
}
printf("\nPart A: \n");
printf("..............................................................................................................\n\n");
char *fn1 = argv[1]; // variables
char *fn2 = argv[2];
int temp = 0;
int counter = 0;
int index = 0;
int index2 = 0;
int sort = 0;
FILE *fp1 = fopen(fn1, "r");
FILE *fp2 = fopen(fn2, "w");
// test if fp1 was opened
if (fp1 == NULL) {
printf("There was an error opening the input file");
return 1;
}
// ints can only hold 10 digits
char data[10];
int *integerArr;
int *tempPointer;
int sizeOfArrs = 10;
integerArr = malloc(sizeOfArrs * sizeof(int));
printf("Reading in the textfile: ");
// reads in the file breaking on each whitespace and ends at the EOF
// pointer
while (fscanf(fp1, "%s", data) != EOF) {
temp = strlen(data);
if (temp > 10) {
printf("\ninteger had too many digits\n");
continue;
}
temp = atoi(data);
integerArr[counter] = temp;
printf(".");
counter++;
if (counter == sizeOfArrs - 1) {
sizeOfArrs += 600;
integerArr = realloc(integerArr, sizeOfArrs * sizeof(int));
}
}
// trim array to actual size needed
sizeOfArrs = counter;
integerArr = realloc(integerArr, sizeOfArrs * sizeof(int));
printf(" Done\n%d Numbers were found\n", counter);
printf("The integers found in the %s file: \n", argv[1]);
// prints the unsorted contents of the file
for (index = 0; index < counter; index++) {
printf("%d ", integerArr[index]);
}
printf("\n\nPart B\n");
printf("..............................................................................................................\n\n");
printf("The integers found in the %s file after sorting: \n", argv[1]);
// best function ever (sorts the array using the cmpfunc to tell if an
// integer is greater than less than or equal to the next one)
qsort(integerArr, counter, sizeof(int), cmpfunc);
// prints the sorted contents of the file
for (index = 0; index < counter; index++) {
printf("%d ", integerArr[index]);
// writes the sorted integers to the new file
fprintf(fp2, "%d ", integerArr[index]);
}
// tests if the write worked
if (fp2 == NULL) {
printf("There was an error writing the outputfile");
}
printf("\n");
// closes both files
fclose(fp1);
fclose(fp2);
return 0;
}
Also, note the fclose's at the bottom. There are a few minor bugs left for you to find.

Resources