#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *f;
f = fopen("my file.txt", "w");
int n = 5;
fprintf(f, "n equals to %d", n);
fclose(f);
f = fopen("my file2.txt", "w");
char *txt = "New file";
fwrite(txt, 1, strlen(txt), f);
fclose(f);
f = fopen("my file3.txt", "w");
char *txt2 = "Hello";
for(int i = 0; i < strlen(txt2); i++)
{
printf("Mouse cursor at %d.\n", ftell(f));
fputc(txt2[i], f);
}
fclose(f);
f = fopen(__FILE__, "r");
char str[1024];
while (!feof(f))
{
fscanf(f, "%s", str);
puts(str);
}
putchar('\n');
fclose(f);
f = fopen(__FILE__, "r");
long size = fseek(f, 0, SEEK_END);
char *buffer = malloc(sizeof(char) * size + 1);
fread(buffer, 1, size, f);
puts(buffer);
free(buffer);
fclose(f);
return 0;
}
Take a look in this part of the code :
f = fopen(__FILE__, "r");
long size = fseek(f, 0, SEEK_END);
char *buffer = malloc(sizeof(char) * size + 1);
fread(buffer, 1, size, f);
puts(buffer);
free(buffer);
fclose(f);
I've tried to print the code in my file and this is what I wrote to do it ^
When I try to print it with puts function it prints 3 characters :
http://i61.tinypic.com/ortdvl.png
The third character is changing in each execution.
Anyway to the question, I don't know why this happens can someone explain me what I did wrong ?
fseek(f, 0, SEEK_END);
long size = ftell(f);
char *buffer = calloc(size + 1, sizeof(char));
rewind(f);
fread(buffer, 1, size, f);
Related
I have a piece of code that is designed to replicate the creation of a .tar file albeit a simpler version of it. It will take in 2 .txt files and produce a .tar file of the 2 files. Below is my code for doing so. However when opening the .tar file it is corrupted and sure enough, by viewing the data in a hex editor the data is cut off.
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#define RECORDSIZE 512
#define NAMSIZ 100
#define TUNMLEN 32
#define TGNMLEN 32
struct header {
char name[NAMSIZ];//needed
char size[12];//needed
};
int main(int argc, char** argv) {
//argv[1] file1 argv[2] file2
char* file1 = argv[1];
char* file2 = argv[2];
FILE* f;
int lSize;
char temp_length[10];
char* file1_data, * file2_data;
int result;
//char* output_str = (char*)malloc(sizeof)
f = fopen(file1, "rb");
if (f == NULL) {
printf("File error!");
return 1;
}
fseek(f, 0, SEEK_END);
lSize = ftell(f);
fseek(f, 0, SEEK_SET);
file1_data = (char*)malloc(sizeof(char) * lSize);
if (file1_data == NULL) {
printf("Memory error!");
return 1;
}
result = fread(file1_data, 1, lSize, f);
file1_data[result] = '\0';
fclose(f);
sprintf(temp_length, "%d", lSize);
struct header* h1 = malloc(sizeof(struct header));
strcpy(h1->name, file1);
strcpy(h1->size, temp_length);
printf("Name:%s Value:%s\n", h1->name, h1->size);
printf("File 1 data:%s\n", file1_data);
f = fopen(file2, "rb");
if (f == NULL) {
printf("File error!");
return 1;
}
fseek(f, 0, SEEK_END);
lSize = ftell(f);
fseek(f, 0, SEEK_SET);
file2_data = (char*)malloc(sizeof(char) * lSize);
if (file2_data == NULL) {
printf("Memory error!");
return 1;
}
result = fread(file2_data, 1, lSize, f);
file2_data[result] = '\0';
fclose(f);
sprintf(temp_length, "%d", lSize);
struct header* h2 = malloc(sizeof(struct header));
strcpy(h2->name, file1);
strcpy(h2->size, temp_length);
printf("Name:%s Value:%s\n", h2->name, h2->size);
printf("File 2 data:%s\n", file2_data);
//allocate mem for output buffer
int total = sizeof(struct header) + sizeof(struct header) + sizeof(file1_data) + sizeof(file2_data);
printf("total length %d\n", total);
f = fopen("Result.tar", "wb");
//fwrite(input,length,no of ele,output buffer)
fwrite(h1, sizeof(struct header), 1, f);
fwrite(file1_data, sizeof(file1_data), 1, f);
fwrite(h2, sizeof(struct header), 1, f);
fwrite(file2_data, sizeof(file2_data), 1, f);
if (fwrite != 0)
printf("Contents to file written successfully !\n");
else
printf("Error writing file !\n");
fclose(f);
}
First file name: File1.txt
Data within:
This is File 1.
Second file name: File2.txt
Data within:
This is File 2.
File 2 has more data inside.
Decoded text output:
File1.txt�ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ31�ÍÍÍÍÍÍÍÍÍThis is File1.txt�ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ63�ÍÍÍÍÍÍÍÍÍThis is
As observed, File 2's name as well as the subsequent data has been cut off. I've been debugging but I'm unsure where am I going wrong as fwrite does not return a 0 hence, I'm assuming it's successful.
As the print statements are exactly what I expected, I don't think the reading of the data is the issue but rather the fwrite function. Hence I would like to seek advice on it.
The error resids in the way you calculate the total length. Indeed, you do not want to use sizeof(file1_data) as the length of the file. Instead you want to use the value returned when reading in result.
Create two variables file1_length and file2_length. Then populate them with the size of their respective file:
...
size_t f1_len, f2_len;
...
f = fopen(file1, "rb");
if (f == NULL) {
printf("File error!");
return 1;
}
fseek(f, 0, SEEK_END);
f1_size = ftell(f);
fseek(f, 0, SEEK_SET);
file1_data = (char*)malloc(sizeof(char) * f1_len);
...
int total = sizeof(struct header) + sizeof(struct header) + f1_len + f2_len;
...
fwrite(h1, sizeof(struct header), 1, f);
fwrite(file1_data, f1_len, 1, f);
fwrite(h2, sizeof(struct header), 1, f);
fwrite(file2_data, f2_len, 1, f);
...
Finally, use these variable as the length of the files' content.
NOTE: The value obtained by sizeof(file1_data) indicate the size of the type. Here, since file1_data is of type char * you get 4.
I'm a beginner to C and wanted to code a simple function that reads the content of file and returns it as a string, as an exercise.
Here is my solution which I think works, but is there any obvious bad practices or unoptimal code here ? For example, I manually added a \0 at the end of the string, but I don't know if it is really necessary...
#include <stdio.h>
#include <stdlib.h>
char *readFile(char *path)
{
//open file
FILE *file = fopen(path, "r");
//if broken
if (file == NULL)
{
printf("Erreur");
return NULL;
}
//return variable
char *result;
//length of the file
int len;
fseek(file, 0, SEEK_END);
len = ftell(file);
fseek(file, 0, SEEK_SET);
//initialising return variable
result = (char*) malloc(sizeof(char) * (len + 1));
int c;
int i = 0;
while (feof(file) == 0)
{
c = fgetc(file);
if (c != EOF)
{
printf("%04x -> %c\n", c, c);
*(result + i) = c;
i++;
}
}
*(result + i) = '\0';
printf("len : %i\n", len);
fclose(file);
return result;
}
I'd replace this:
int c;
int i = 0;
while (feof(file) == 0)
{
c = fgetc(file);
if (c != EOF)
{
printf("%04x -> %c\n", c, c);
*(result + i) = c;
i++;
}
}
with this:
fread(file, 1, len, result);
It's much shorter
It's correct
It's certainly faster
There is still room for improvement though, for example you could add error handling, fread can fail.
Since you have already got the length of the file to be read, you could also read them at once instead char-by-char.
Another implmentation of your function, for example:
char *readFile(char *path)
{
//open file
FILE *file = fopen(path, "r");
//if broken
if (file == NULL)
{
printf("Erreur");
return NULL;
}
//return variable
char *result;
//length of the file
int len;
fseek(file, 0, SEEK_END);
len = ftell(file);
fseek(file, 0, SEEK_SET);
//initialising return variable
result = (char*) malloc(sizeof(char) * (len + 1));
size_t i = fread(result, sizeof(char), len, file);
*(result + i) = '\0';
printf("len : %i\n", len);
fclose(file);
return result;
}
int main()
{
FILE* bfp = fopen("student.dat", "wb");
int n = 1452;
fseek(bfp, 0, SEEK_SET);
fwrite(&n, sizeof(int), 1, bfp);
FILE* rfp = fopen("student.dat", "rb");
int read = 0;
fread(&read, sizeof(read), 1, rfp);
printf("%d", read);
fclose(bfp);
fclose(rfp);
return 0;
}
Why do I get 0 when I print it out?
I tried "w" mode, but it didn't work. How can I enter it?
OK now am half the way ,This is what i've done:
`int main(int argc,char* argv[]){
FILE *inputFile,*outputFile;
unsigned char *inputBuffer, *outputBuffer;
unsigned char *readMod = "r";
int result,x;
long int outputSize;
long int outputSizeun;
size_t inputSize;
if(argc >= 3){
inputFile = fopen(argv[2],readMod );
// get length of input
fseek(inputFile, 0, SEEK_END);
inputSize = ftell(inputFile);
fseek(inputFile, 0, SEEK_SET);
//allocate the inputBufer size
inputBuffer = (unsigned char *)malloc(inputSize);
fread(inputBuffer, 1, inputSize, inputFile);
outputSize = EZ_COMPRESSMAXDESTLENGTH(inputSize);
//allocate the outputBuffer size
outputBuffer = (unsigned char *)malloc(outputSize);
//check for the -z(compression)/-u(decompression) option s
if(strcmp("-z",argv[1])==0){
result = ezcompress(outputBuffer, &outputSize, inputBuffer, inputSize);
}else if(strcmp("-u",argv[1])==0){
result = ezuncompress(outputBuffer, &outputSizeun, inputBuffer, inputSize);
}else{
printf("Error : unknown operation \" %s \" type -z for compression or -u for decompression\n",argv[1]);
}
if (result == 0) {
// if the output filename was not present it output the compressed data into a file named "compress"
if(argv[3] == NULL){ argv[3] = "output";}
//write the output
outputFile = fopen(argv[3], "w");
fseek(outputFile, 0, SEEK_END);
fseek(outputFile, 0, SEEK_SET);
fwrite(outputBuffer, 1, outputSize, outputFile);
fclose(outputFile);
} else {
// Something went wrong
printf("%d ",result);
}
//now freeing buffers
free(inputBuffer);
free(outputBuffer);
}else{
printf("insufficnt Arguments :-s");
return 1;
}
return 0;
}
why does this code returns -3 when i run **a.exe -u output
ezcompress and ezuncompress work on the file data directly which are represented as arrays of characters.
for (int i = 1; i < argc; i++) {
// open argument you want to compress
FILE *inputFile = fopen(argv[i], "r");
// get length of input
// http://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c
fseek(inputFile, 0, SEEK_END);
size_t inputSize = ftell(inputFile);
fseek(inputFile, 0, SEEK_SET);
unsigned char *inputBuffer = (unsigned char *)malloc(inputSize);
fread(inputBuffer, 1, inputSize, inputFile);
long outputSize = EZ_COMPRESSMAXDESTLENGTH(sz);
unsigned char *outputBuffer = (unsigned char *)malloc(outputSize);
int result = ezcompress(outputBuffer, &outputSize, inputBuffer, inputSize);
if (result != EZ_BUF_ERROR) {
// Do stuff with outputBuffer which has length outputSize
} else {
// Something went wrong
}
free(intputBuffer);
free(outputBuffer);
}
#include <Windows.h>
#include <stdio.h>
int count = 0;
FILE* pFile = 0;
long Size = 0;
void *memfrob(void * s, size_t n)
{
char *p = (char *) s;
while (n-- > 0)
*p++ ^= 42;
return s;
}
int main()
{
fopen_s(&pFile, "***", "r+");
fseek(pFile, 0, SEEK_END);
Size = ftell(pFile);
char *buffer = (char*)malloc(Size);
memset(buffer, 0, Size);
fread(buffer, Size, 1, pFile);
fclose(pFile);
memfrob(buffer, Size);
fopen_s(&pFile, "***", "w+");
fwrite(buffer, Size, 1, pFile);
fclose(pFile);
}
Hi, fread isn't reading anything from file to buffer and I can't figure out why. Could someone give me a hint or a push in the right direction?
You need to seek back to the beginning of the file before you fread.
You did a fseek to the end of the file and didn't fseek back before you did the fread.