I have a project; a kind of a anti-virus, to search whether a virus is in a file. My idea was to get a length of the virus and jump by one every time I reach the the length but I don't know how to do it exactly.
int virusChaek(FILE* file, char virus[],char filesNames[], int len)
{
char* pch;
int sizeOfFile = 0;
int i = 0;
int arr[100] = {0};
int* myArr;
int isVirus = 0;
file = fopen(filesNames, "rb");
if (file == NULL)
{
printf("file does not exist.");
return 1;
}
fseek(file, 0, SEEK_END);
sizeOfFile = ftell(file);
fseek(file, 0, SEEK_SET);
myArr = (int*)malloc(sizeof(int) * strlen(virus));
while (0 < (sizeOfFile))
{
fread(arr, 1, 1, file);
printf("arr[0] = %d\n", arr[0]);
myArr[i] = arr[0];
printf("myArr = %d\n", myArr[i]);
sizeOfFile--;
i++;
}
free(myArr);
fclose(file);
return 0;
}
Related
If I am dynamically allocating an array of pointers to chars(strings). why I cant place the content of the *word inside a given position in my array like so array[i] = word or array[i] = *word.
I want to split and store the words in a file into a dynamically allocated array. Is this the right direction or is it done through a 2D array.
int main(int argc, char *argv[]) {
FILE *file = fopen(argv[1], "r");
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
char *array = malloc(size * sizeof(char)+10);
char *array2 = malloc(size * sizeof(char)+10);
fread(array, 1, size, file);
array[size] = '\0';
char *word;
word = strtok (array, " ,.-");
int i = 0;
while (i <= 9 && word != NULL ){
for(i = 0; i < 10; i++) {
array[i] = *word;
strcpy(&array2[i], word);
word = strtok (NULL, " ,.-");
}
fclose(file);
}
for (i = 0; i < 10; ++i)
printf("array[%d] = %c\n", i, array2[i]);
free(array);
free(array2);
fclose(file);
return 0;
}
text to read.
This free test evaluates how well you understand what you
current output
array2[0] = T
array2[1] = f
array2[2] = t
array2[3] = e
array2[4] = h
array2[5] = w
array2[6] = y
array2[7] = u
array2[8] = w
array2[9] = y
What Id like to get.
array2[0] = The
array2[1] = free
array2[2] = test
array2[3] = evaluates
array2[4] = how
array2[5] = well
array2[6] = you
array2[7] = understand
array2[8] = what
array2[9] = you
You need two different arrays
The first is the buffer you read the data into - lets call that 'buffer', its a char*
The second is an array of pointers to 'strings' - lets call that 'words' its a char**
int main(int argc, char* argv[]) {
FILE* file = fopen("dict.txt", "r");
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = malloc(size * sizeof(char) + 10);
char** words = malloc(sizeof(char*) * 10);
fread(buffer, 1, size, file);
buffer[size] = '\0';
char* word;
word = strtok(buffer, " ,.-");
int i = 0;
while (i <= 9 && word != NULL) {
for (i = 0; i < 10; i++) {
words[i] = word;
word = strtok(NULL, " ,.-");
}
fclose(file);
}
for (i = 0; i < 10; ++i)
printf("array[%d] = %s\n", i, words[i]);
free(buffer);
free(words);
fclose(file);
return 0;
}
I will comment on the complete lack of tests to check if anything worked, PLus I have hardcede to 10 words - since you have done that in the loop it seems.
Also note that the 'words' array if full of pointers to the 'buffer'. If you delete or change 'buffer' 'words' will be invlaid
How to sort the output array? Displays the frequency of occurrence of a word in a different, disordered order. I would like him to output words in descending order, from larger to smaller. How can I implement this sorting?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char** words = NULL;
int num_words = 0;
char* delim = " \t\n,.!?:";
int size_file = 0;
FILE* fp = fopen("test.txt", "r");
fseek(fp, 0, SEEK_END);
size_file = ftell(fp);
printf("%d\n", size_file);
char* buffer = calloc(size_file + 1, sizeof(char)); //буфер
if (buffer == NULL) {
printf("Error\n");
exit(-1);
}
fseek(fp, 0, SEEK_SET);
fread(buffer, 1, size_file, fp);
printf("\nText file\n\n");
printf("%s\n", buffer);
char* istr = strtok(buffer, delim);
while (istr) {
words = realloc(words, (num_words + 1) * sizeof(char*));
words[num_words++] = istr;
istr = strtok(NULL, delim);
//printf("%s\n", istr);
}
/*for (int i=0; i<num_words;i++) {
printf("%p\n", words[i]);
}*/
printf("Number of characters in file :%d\n", size_file);
printf("Number of words in file :%d\n\n", num_words);
for (int i = 0; i < num_words; i++) {
puts(words[i]);
}
int* wcnt = calloc(num_words, sizeof(int));
char* is_first = calloc(num_words, sizeof(char));
for (int i = 0; i < num_words; i++) {
wcnt[i]++;
for (int j = 0; j < num_words; j++) {
if (i != j && strcmp(words[i], words[j]) == 0) {
if (wcnt[i]++ == 1 && i < j)
is_first[i] = 1;
}
}
}
for (int i = 0; i < num_words; i++) {
if (wcnt[i] == 1 || is_first[i])
if (wcnt[i] > 1 ) {
printf("%s = %d\n", words[i], wcnt[i]);
}
}
fclose(fp);
free(buffer);
free(words);
free(wcnt);
free(is_first);
return 0;
}
How to sort the output array? Displays the frequency of occurrence of a word in a different, disordered order. I would like him to output words in descending order, from larger to smaller. How can I implement this sorting? for instance
"the"=4;
"was"=3;
....
So here is the program to reverse content of a file block by block.
#include <stdio.h>
#include <stdlib.h>
#define BS 12
void reverse(char * buffer, int size)
{
char tmp;
int i;
for(i = 0; i < size / 2; i++)
{
tmp = (char)buffer[i];
buffer[i] = buffer[size - i - 1];
buffer[size - i - 1] = tmp;
}
}
int main (const int argc, const char** argv)
{
if(argc != 3)
exit(-1);
char * buffer = malloc(BS);
FILE * f1, * f2;
f1 = fopen(argv[1], "r");
f2 = fopen(argv[2], "w");
fseek(f1, 0, SEEK_END);
long i = ftell(f1);
// long f1_len = ftell(f1);
// unsigned char tmp;
int if_end = 1;
int need = 0;
int count;
do
{
i = i - BS;
if(i < 0)
{
need = BS - abs(i);
i = 0;
}
else
need = BS;
fseek(f1, i, SEEK_SET);
if(if_end) // strip EOF
{
count = fread(buffer, need - 1, 1, f1);
if_end = 0;
}
else
count = fread(buffer, need, 1, f1);
reverse(buffer, count);
fwrite(buffer, count, 1, f2);
if(i == 0)
break;
}while(i > 0);
fclose(f1);
fclose(f2);
free(buffer);
return 0;
}
testfile:
$ xxd testfile
0000000: 6162 6364 6566 670a abcdefg.
$ gcc test.c -o test
$ ./test testfile testfile2
$ xxd testfile2
0000000: 61 a
Any idea where is wrong? I have been debugging this for long time.
Your problem is that fwrite returns the number of successful blocks, not the number of bytes.
So reverse(buffer, count); needs to be reverse(buffer,count * need)
Similairly the write to the output needs to be fwrite(buffer, count * need, 1, f2);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BS 12
void reverse(char * buffer, int size)
{
char tmp;
int i;
for(i = 0; i < size / 2; i++)
{
tmp = (char)buffer[i];
buffer[i] = buffer[size - i - 1];
buffer[size - i - 1] = tmp;
}
}
int compare_bin(char * buffer, char * buffer2, int size)
{
// because strncmp is only for string without \x00, so there must be a customized compare function
int i;
for(i = 0; i < size; i++)
{
if(buffer[i] != buffer2[i])
return 0;
}
return 1;
}
int main (const int argc, const char** argv)
{
if(argc != 3)
exit(-1);
int equal = 1;
char * buffer = malloc(BS), * buffer2 = malloc(BS);
FILE * f1, * f2;
f1 = fopen(argv[1], "r");
f2 = fopen(argv[2], "r");
fseek(f1, 0, SEEK_END);
fseek(f2, 0, SEEK_END);
long i = ftell(f1), j = ftell(f2);
if(i != j)
{
equal = 0;
goto endp;
}
fseek(f2, 0, SEEK_SET);
int need = 0;
int count;
int f2_pos = 0;
do
{
i = i - BS;
if(i < 0)
{
need = BS - abs((int)i);
i = 0;
}
else
need = BS;
fseek(f1, i, SEEK_SET);
count = fread(buffer, need, 1, f1);
reverse(buffer, count * need);
// fwrite(buffer, count * need, 1, f2);
fread(buffer2, need * need, 1, f2);
// printf("compare...\n");
// for(int i = 0; i < need * count; i++)
// {
// printf("%02hhX", buffer[i]);
// }
// printf("\n");
// for (int i = 0; i < need * count; i++)
// {
// printf("%02hhX", buffer2[i]);
// }
// printf("\n");
if(compare_bin(buffer, buffer2, need * count) == 0)
{
equal = 0;
break;
}
f2_pos += need * count;
fseek(f2, f2_pos, SEEK_SET);
if(i == 0)
break;
}while(i > 0);
fclose(f1);
fclose(f2);
free(buffer);
free(buffer2);
endp:
if(equal)
return 0;
else
{
printf("2 files not equal is reversed order\n");
return 1;
}
return 0;
}
So I write a program to compare file content in reverse order. I have already considered \x00 in binary file and strncmp isn't used. But there is still flaw. There is a test server to test this program. But I dont have access to it. This program always fails on that server. So there must be some special cases to make it fail. Any idea?
There are other ways around it. For instance, calculating MD5. But I want to fix this.
For the very first iteration where you read data you have
fread(buffer2, need * need, 1, f2);
The problem is that in that case need is 12, which is the size of the memory allocated for buffer2, but you ask to read 12 * 12 bytes.
If the second file is large enough, you will write out of bounds in the memory, leading to undefined behavior. If the file is not large enough then you won't read anything.
Also note that the order of the two middle arguments to fread matter. If you changed the order you would write out of bounds of the buffer both if the file is larger than need * need or not. You should really read count byte-sized object (the second argument should be 1 and the third should be count, which of course mean you need to change the order in the first call as well).
In short, your two fread calls should be
count = fread(buffer, 1, BS, f1);
fread(buffer2, 1, count, f2);
PS. Don't forget error checking.
UPDATE***********************
For reference I included the program I made for opening a PPM image - embedding a message into the image and then saving out a new image with the embedded text. With the function below I'm hoping to extra that message, (hidden in the LSB) and then converting it to text to display it. Thanks for the replies so far - I'm going to start testing them out and see if anything works.
I'm trying to write a function that extracts the LSB of an unsigned char value - puts them bits together to form an extracted message. I have the length of how many LSBs I need to extract from the file, but I'm having trouble with how to convert this into a message.
At first I extracted the first 8 bits into an int array - giving me something such as 00110000. Now I have an INT array with that value, and I need to convert it to a single char for the letter representation. However, I think I should be taking in all of the LSBs into an array that is messageLength * 7 and somehow converting that int array into the text. It would be giving me the binary represenation of the text before converting. Maybe theirs a way to convert a long string of 1's and 0's to text?
unsigned char * extBits(PPMImage *img, int messageLen, unsigned char * decMsg)
{
//int count = 2;
int embCount = 0;
int deM = messageLen * 7;
int count = 0;
unsigned char byte;
// int mask;
// unsigned char update;
// unsigned char flipOne = 0x01; //0x01
// unsigned char flipZero = 0xFE; //0x00
unsigned char dMsg[deM];
int byteArray[7];
int takeByte = 0;
unsigned char *extMsg;
char c;
for(int j = 0; j < 7; j++)
{
if(takeByte == 8)
{
//first letter extracted
takeByte = 0;
}
//byte = msgOne[j];
// byte = img->pixel[j];
//encMsg[j] = byte;
byte = img->pixel[j];
//printf("byte: %c\n", byte);
// printf("byte: %x\n", byte);
byte &= 1;
//printf("byte after: %x\n", byte);
dMsg[j] = byte;
byteArray[j] = byte;
data[j] = byteArray[j];
printf("dMsg:%x ", dMsg[j]);
// printf("pixel:%c \n", img->pixel[j]);
embCount++;
takeByte++;
}
/*
for(int r=0;r<7;r++)
{
printf("\n%d\n", byteArray[r]);
}
printf("count: %d", embCount);
printf("%s ", dMsg);
*/
return decMsg = dMsg;
}
embedding program*******
//////////////////////////////////////////////////////////////
/*
execute as ./emb -i <img2embed> -i <text file> -o <embedIMG>
*/
//////////////////////////////////////////////////////////////
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct {
int x, y;
unsigned char *pixel;
} PPMImage;
#define RGB_COMPONENT_COLOR 255
static PPMImage *readPPM(const char *filename)
{
FILE * fp;
PPMImage *img;
int rgb_comp_color;
int size = 0;
fp = fopen(filename, "a+");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
unsigned char *buff;
unsigned char stuff[16];
int c;
int x,y;
buff = (unsigned char*) malloc(sizeof(unsigned char)*size +1);
memset(buff, '\0', sizeof(unsigned char)*size+1);
fgets(stuff, sizeof(stuff), fp);
if (stuff[0] != 'P' || stuff[1] != '3') {
fprintf(stderr, "Invalid image format (must be 'P3')\n");
exit(1);
}
//alloc memory form image
img = (PPMImage*)malloc(sizeof(PPMImage));
if (!img) {
fprintf(stderr, "Unable to allocate memory\n");
exit(1);
}
c = getc(fp);
while (c == '#') {
while (getc(fp) != '\n') ;
c = getc(fp);
}
ungetc(c, fp);
if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) {
fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
exit(1);
}
if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
exit(1);
}
if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
fprintf(stderr, "'%s' does not have 8-bits components\n",filename);
exit(1);
}
//printf("x: %d y: %d\n", img->x, img->y);
unsigned char buffer[1024];
memset(buffer,0,1024);
fgets(buffer,1024,fp);
fread(buff, 1, size, fp);
img->pixel = buff;
/*
for(int h = 0; h < 20; h++)
{
printf("%c", buff2[h]);
}
printf("%s", buff2);
*/
fclose(fp);
return img;
}
void writePPM(const char *filename, unsigned char * img, int x, int y)
{
FILE *fp;
//open file for output
fp = fopen(filename, "wb");
if (!fp) {
fprintf(stderr, "Unable to open file '%s'\n", filename);
exit(1);
}
//write the header file
//image format
fprintf(fp, "P3\n");
//comments
// fprintf(fp, "# Created by %s\n",CREATOR);
//image size
fprintf(fp, "%d %d\n",x,y);
// rgb component depth
fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);
// pixel pixel
fwrite(img,1, strlen(img), fp);
fclose(fp);
}
//unsigned char * embBits(PPMImage *img, int messageLen, unsigned char*msgOne, unsigned char *encMsg)
int embBits(PPMImage *img, int messageLen, unsigned char*msgOne, int embLen)
{
//int count = 2;
int embCount = 0;
int count = 0;
unsigned char *eMsg;
unsigned char byte;
int mask;
unsigned char update;
unsigned char flipOne = 0x01; //0x01
unsigned char flipZero = 0xFE; //0x00
for(int j = 0; j < messageLen; j++)
{
byte = msgOne[j];
//encMsg[j] = byte;
for(int k=7; 0 < k; k--)
{
update = byte;
update = update & (1<<k);
//printf("pixel:%c\n", img->pixel[count]);
//printf("pixel+1:%c\n", img->pixel[count+1]);
// printf("pixel+2:%c\n", img->pixel[count+2]);
if(update == 0)
{
// if i see 1 |=
// if i see a 0 &=
//img->pixel[count] = img->pixel[count] &= flipZero;
img->pixel[count+2] &= flipZero;
}
else
{
//flip bit
//red
//check LSB and FLIP
// img->pixel[count] = img->pixel[count] |= flipOne;
img->pixel[count+2] |= flipOne;
}
//mask--;
//eMsg[count] = img->pixel[count];
//printf("count: %d\n", count);
count = count + 3;
}
// eMsg[j] = byte;
}
//return encMsg = eMsg;
//unsigned char *yes = "sucess";
/*
for(int a = 0; a < messageLen; a++)
{
printf("pixel: %c", img->pixel[a]);
printf("msg: %c\n", eMsg[a]);
// eMsg[a] = img->pixel[a];
}
*/
embCount = count;
return embLen = embCount;
}
int main(int argc, char **argv){
int messageLen;
int i = 0;
PPMImage *img;
int size = 0;
FILE * fp;
int testSize;
fp = fopen(argv[4], "a+");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
unsigned char *buff;
buff = (unsigned char*) malloc(sizeof(unsigned char)*size +1);
memset(buff, '\0', sizeof(unsigned char)*size+1);
fread(buff, 1, size, fp);
fclose(fp);
// printf("text encryption: %s\n", buff);
testSize = strlen(buff);
// printf("Size of text %d\n", testSize);
messageLen = strlen(buff);
img = readPPM(argv[2]);
/*
int testing = strlen(img->pixel);
for (int f=0;f<6;f++)
{
//f2 = 1
//f3 = 6
printf("%c", img->pixel[f]);
}
*/
// printf("%c \n", img->pixel[2]);
// printf("%c \n", img->pixel[5]);
printf("\n");
// unsigned char * encMsg;
int encMsg = 0;
encMsg = embBits(img, messageLen, buff, encMsg);
// printf("cipher msg:%s\n", img->pixel);
printf("message length: %d\n", messageLen);
// printf("cipher msg length: %d\n", encMsg);
writePPM(argv[6], img->pixel, img->x, img->y);
printf("Please press enter to complete\n");
getchar();
}
I don't know what you are doing specifically with your file and assigning each bit to a position in an array but you can print binary sequences stored in a unsigned int. Try using something like this...
#include <stdio.h>
int main() {
unsigned int arr[] = {00110110, 00111100, 10111011};
int i = sizeof(arr)/sizeof(arr[0]);
while(i-->0) {
printf("%c, ", arr[i]);
}
printf("\n");
}
You can use bit operations to gather these bits into a byte.
#include <stdio.h>
#define BYTE_LENGTH 8
#if 1
/* MSB is in data[0], LSB is in data[BYTE_LENGTH - 1] */
int arrayToChar(const int data[]) {
int c = 0;
int i;
for (i = 0; i < BYTE_LENGTH; i++) {
if (data[i]) c |= (1 << (BYTE_LENGTH - 1 - i));
}
return c;
}
#else
/* LSB is in data[0], MSB is in data[BYTE_LENGTH - 1] */
int arrayToChar(const int data[]) {
int c = 0;
int i;
for (i = 0; i < BYTE_LENGTH; i++) {
if (data[i]) c |= (1 << i);
}
return c;
}
#endif
int main(void) {
int data[8] = {0, 0, 1, 1, 0, 0, 0, 0};
int c = arrayToChar(data);
printf("%d %c\n", c, c);
return 0;
}
If you want to produce one byte from 7 bits, change BYTE_LENGTH to 7.
If you want to deal with long sequence of bits, apply arrayToChar repeatedly with changing the (address of) first element to be passed.