I am currently trying to create a binary byte patcher but got stuck at one little issue.
When trying to read the input file byte by byte and simultanously writing these bytes to an output file, newline characters are somehow doubled.
An input like that:
line1
line2
line3
Would look like:
line1
line2
line3
The actual program is a bit more complex but this abstract should give an idea of what I'm trying to do.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SECTOR 32
int main(int argc, char** argv) {
FILE* input = fopen(INPUT_FILE, "r");
FILE * output = fopen(OUTPUT_FILE, "w");
int filesize = size of opened file...
char buffer[16] = {0};
int i = 0;
while(i < filesize) {
fseek(input, i, SEEK_SET);
fread(buffer, sizeof(char), SECTOR, input);
if(cmp buffer with other char array) {
do stuff
} else {
i++;
fwrite(&buffer[0], sizeof(char), 1, output);
}
}
print rest of buffer to the file to have the past SECTOR-1 bytes aswell...
fclose(input);
fclose(output);
return 1;
}
Try to use open,close,read ans write instead of fopen fread fwrite and fclose. You should get something like that:
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFFSIZE 32
int main(int argc, char** argv) {
int input = open(INPUT_FILE, O_RDONLY);
int output = open(OUTPUT_FILE, O_WRONLY | O_CREATE, S_IWUSR | S_IRUSR);
int i = 0;
char buffer[BUFFSIZE];
while((i = read(input, buffer, BUFFSIZE))) {
if(cmp buffer with other char array) {
do stuff
} else {
while (i < 0) {
i--;
write(output, &buffer[i], sizeof(char));
}
}
}
close(input);
close(output);
return 1;
}
Related
I would like to read data from a file, I need to open file in binary form and read blocks of data at a time?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char* argv[])
{
int n;
FILE * fp;
size_t nbyte;
unsigned char * buffer[1024];
fp=open("file_test.txt",O_RDONLY);
read(fp,buffer,1);
printf("%s\n",buffer[0]);
close(fp);
return 0;
}
open/read is the POSIX version of fopen/fread, open does not return FILE* pointer.
unsigned char * buffer[1024]; is for array of character strings. You just need a buffer unsigned char buffer[1024];
printf("%s\n",...); is for printing c-string, it cannot print binary data in general.
int main(void)
{
int fin = open("file_test.txt", O_BINARY | O_RDONLY);
if (!fin)
return 0;
unsigned char buffer[1024];
while (1)
{
size_t size = read(fin, buffer, sizeof(buffer));
if (size == 0)
break;
for (size_t i = 0; i < size; i++)
printf("%02X ", buffer[i]);
//break; print the whole file!
}
close(fin);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define LSIZ 128
#define RSIZ 10
int main()
{
// gets input from input.txt
char *filename = "input.txt";
FILE *fptr;
fptr = fopen(filename, "r");
int i = 0, j, tot = 0;
char line[RSIZ][LSIZ];
// inputs text content into array
while(fgets(line[i], LSIZ, fptr) != NULL)
{
line[i][strlen(line[i]) - 1] = '\0';
i++;
}
printf("\n");
tot = i;
printf("\nThe content of the file %s are: \n",filename);
for(j = 0; j < tot; ++j)
printf(" %s\n", line[i]);
//convert into hex of crc32
const char *s = line[i];
printf("%s's crc32 in hex: ",filename);
printf("%lX\n", crc32(0, (const void*)s, strlen(s)));
return 0;
}
I can't seem to get the code to work as intended. I am using vim while also compiling on an Ubuntu Terminal for this code. I wanted this to get the text from input.txt, store it into the array and create crc32 hex of said input. However, this output is the result:
The content of the file input.txt are:
input.txt's crc32 in hex: 0
There is definitely something wrong with the char inputting but, after browsing, I seemed to hit the wall on this. Any help would be appreciated!
I edited your question, removing the answer you added to it, and posted that answer here.
My code is running perfectly now. I will write the the whole thing here for other's reference:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define LSIZ 128
#define RSIZ 10
int main(int argc, const char * argv[])
{
// gets input from input.txt
char *filename = "input.txt";
FILE *fptr;
fptr = fopen(filename, "r");
int i = 0, j, tot = 0;
char line[RSIZ][LSIZ];
// inputs text content into array
while(fgets(line[i], LSIZ, fptr) != NULL)
{
line[i][strlen(line[i]) - 1] = '\0';
i++;
}
tot = i;
printf("The content of the file %s are: ",filename);
for(j = 0; j < tot; ++j)
printf("%s\n", line[j]);
//convert into hex of crc32
const char *s = line[0];
printf("%s's crc32 in hex: ",filename);
printf("%lX\n", crc32(0, (const void*)s, strlen(s)));
fclose(fptr);
return 0;
}
This is the output with "Hello World" inside input.txt file:
The content of the file input.txt are: Hello World
input.txt's crc32 in hex: 4A17B156
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int read_file(char* filename, char **buffer) {
FILE* file1;
file1 = fopen(filename, "r");
//gets the size of the file
struct stat st;
stat(filename, &st);
int size = st.st_size;
*buffer = malloc(size);
fread(*buffer, size, 1, file1);
fclose(file1);
return size;
}
void write_file(char* filename, char*buffer, int size) {
FILE* file2 = fopen(filename, "w"); int k;
for (k = size - 1; k >= 0; k--) {
fwrite(buffer + k, 1, 1, file2);
}
fclose(file2);
}
int main(int argc, char *argv[]) {
char* buffer;
char* filename1;
char* filename2;
int filesize;
//create an array and for loop to call the fread more than once
filename1 = "Bible.txt";
filename2 = "reverse.txt";
filesize = read_file(filename1, &buffer);
write_file(filename2, buffer, filesize);
free(buffer);
return 0;
}
Some info: I was able to successfully reverse a text file of a textbook, however I used iterative. It is also supposed to be written recursively but I keep getting stack errors. Any ideas are appreciated on what I can try.
Write the program myuniq.c that contains a function void process_file(FILE* f) that reads all input from the given file one line at the time while keeping two consecutive lines in memory, and prints each line to the standard output if it is not equal to the previously read line.
^^This is the assignment i'm working on. My code below is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void process_file(FILE* f);
int main()
{
FILE *fil = fopen("text.txt","r");
process_file(fil);
return 0;
}
void process_file(FILE* f)
{
FILE *fi = f;
char *firstLine = fgets(firstLine, 999, f);
char *secondLine = fgets(secondLine, 999, f);
while (feof(fi))
{
if (firstLine == secondLine)
{
puts(secondLine);
}
else
{
puts(firstLine);
puts(secondLine);
}
firstLine++;
secondLine++;
}
}
It compiled fine...but on every run it says core dumped. I can't see where I went wrong? Any ideas?
You don't check the return value of fopen, you don't allocate any memory for the strings into which you read, you don't continue reading input from the file, you don't correctly check for the end of input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MY_MAX_LINE 999
void process_file(FILE* f)
{
char firstLine[MY_MAX_LINE + 1];
char secondLine[MY_MAX_LINE + 1];
while (1)
{
if (!fgets(firstLine, sizeof(firstLine), f))
break;
puts(firstLine);
if (!fgets(secondLine, sizeof(secondLine), f))
break;
if (strncmp(firstLine, secondLine, sizeof(firstLine)))
puts(secondLine);
}
if (!feof(f))
perror("Problem reading from file"), exit(1);
}
int main(int argc, char **argv)
{
FILE *f = fopen("text.txt", "r");
if (!f)
perror("text.txt"), exit(1);
process_file(f);
fclose(f);
return 0;
}
I have to create a function that reads a file called grwords.txt containing around 540000 words which are written in Greek letters.
I have to convert these words to uppercase and fill an array called char **words.
This is what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <ctype.h>
void fp();
int main(int argc, char *argv[]) {
SetConsoleOutputCP(1253);
fp();
return 0;
}
void fp(){
char **words;
words = malloc(546490 * sizeof(int *));
for (i = 0; i < 546490; i++)
words[i] = malloc(24 * sizeof(int));
FILE *file;
char *word;
size_t cnt;
file = fopen("grwords.txt", "rt");
if (file == NULL){
printf("File cannot be opened.\n");
exit(1);
}
cnt = 0;
while (1==fscanf(file, "%24s",word)){
if (cnt == 546490)
break;
strcpy(words[cnt++], word);
}
fclose(file);
}
I'm still trying to figure out pointers. I know that & makes a pointer from a value and * a value from a pointer. Updated the program and it successfully fills the array with the words from the file! I still have no idea how to convert Greek lowercase to uppercase.
Handling Greek words can be dependent on your platform.
First of all, you need to understand how file handling works. Here is what I wrote:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define bufSize 1024 // max lenght of word
// we are going to receive the .txt from cmd line
int main(int argc, char *argv[])
{
FILE *fp;
// Assume file has max 10 words
const size_t N = 10;
// Allocate a 2D array of N rows
// and bufSize columns.
// You can think of it like an array
// of N strings, where every string
// has, at most, bufSize length.
char buf[N][bufSize];
// make sure we got the .txt
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
// open the file
if ((fp = fopen(argv[1], "r")) == NULL)
{ /* Open source file. */
perror("fopen source-file");
return 1;
}
// we will use that for toupper()
char c;
// counters
int i = 0, j;
while (fscanf(fp, "%1024s", buf[i]) == 1)
{ /* While we don't reach the end of source. */
/* Read characters from source file to fill buffer. */
// print what we read
printf("%s\n", buf[i]);
j = 0;
// while we are on a letter of word placed
// in buf[i]
while (buf[i][j])
{
// make the letter capital and print it
c = buf[i][j];
putchar (toupper(c));
j++;
}
i++;
printf("\ndone with this word\n");
}
// close the file
fclose(fp);
return 0;
}
For this test.txt file:
Georgios
Samaras
Γιώργος
Σαμαράς
the code would run as:
./exe test.txt
Georgios
GEORGIOS
done with this word
Samaras
SAMARAS
done with this word
Γιώργος
Γιώργος
done with this word
Σαμαράς
Σαμαράς
done with this word
As you can see, I could read the Greek words, but failed to convert them in upper case ones.
Once you got how file handling goes, you need to use wide characters to read a file with Greek words.
So, by just modifying the above code, we get:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#define bufSize 1024
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE *fp;
const size_t N = 15;
wchar_t buf[N][bufSize];
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("fopen source-file");
return 1;
}
wchar_t c;
int i = 0, j;
while (fwscanf(fp, L"%ls", buf[i]) == 1)
{
wprintf( L"%ls\n\n", buf[i]);
j = 0;
while (buf[i][j])
{
c = buf[i][j];
putwchar (towupper(c));
j++;
}
i++;
wprintf(L"\ndone with this word\n");
}
fclose(fp);
return 0;
}
And now the output is this:
Georgios
GEORGIOS
done with this word
Samaras
SAMARAS
done with this word
Γιώργος
ΓΙΏΡΓΟΣ
done with this word
Σαμαράς
ΣΑΜΑΡΆΣ
done with this word
I see that you may want to create a function which reads the words. If you need a simple example of functions in C, you can visit my pseudo-site here.
As for the 2D array I mentioned above, this picture might help:
where N is the number of rows (equal to 4) and M is the number of columns (equal to 5). In the code above, N is N and M is bufSize. I explain more here, were you can also found code for dynamic allocation of a 2D array.
I know see that you are on Windows. I tested the code in Ubuntu.
For Windows you might want to take a good look at this question.
So, after you read all the above and understand them, you can see what you asked for with dynamic memory management.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#define bufSize 1024
wchar_t **get(int N, int M);
void free2Darray(wchar_t** p, int N);
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE *fp;
const size_t N = 15;
wchar_t** buf = get(N, bufSize);
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("fopen source-file");
return 1;
}
wchar_t c;
int i = 0, j;
while (fwscanf(fp, L"%ls", buf[i]) == 1)
{
wprintf( L"%ls\n", buf[i]);
j = 0;
while (buf[i][j])
{
c = buf[i][j];
putwchar (towupper(c));
j++;
}
i++;
wprintf(L"\ndone with this word\n");
}
fclose(fp);
// NEVER FORGET, FREE THE DYNAMIC MEMORY
free2Darray(buf, N);
return 0;
}
// We return the pointer
wchar_t **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i;
wchar_t **table;
table = malloc(N*sizeof(wchar_t *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(wchar_t) );
return table;
}
void free2Darray(wchar_t** p, int N)
{
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
Note that this code is expected to work on Linux (tested on Ubuntu 12.04), not on Windows (tested on Win 7).