Why the output the program is something different? - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *fp;
char ch;
char buffer[80] ;
fp = fopen("c:\\Rasmi Personal\\hello.txt", "w");
if(fp == NULL)
{
printf("File not found");
exit(1);
}
else
{
while(1)
{
gets(buffer);
fwrite(buffer, strlen(buffer), 2, fp); /* I made, size_t nitems = 2 (third element/argument)*/
fwrite("\n", 1, 1, fp);
}
}
fclose(fp);
return 0;
}
Input:
Rasmi Ranjan Nayak
Output:
Rasmi Ranjan Nayak 0# ÿ" 8ÿ"
Why this garbage is coming.
According to fwrite() function. if the size_t nitems is more than 1 then the entered text will be written more than once.
But here why I am getting garbage?

You're telling fwrite() to write two times strlen(buffer) bytes from the buffer (by setting nmemb = 2 you're making it write two "objects", each of which is strlen(buffer) bytes long), so it reads twice the number of bytes that are actually present.
The "garbage" is simply whatever happens to appear in memory after the string ends in buffer.
This is broken code, nmemb should be 1.

The signature of fwrite function is
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
ptr
Pointer to the array of elements to be written.
size
Size in bytes of each element to be written.
count
Number of elements, each one with a size of size bytes.
stream
Pointer to a FILE object that specifies an output stream.
In this case, if you try to write count * size who is bigger (in bytes) than the original string you have this garbage. If you clean the buffer
memset(buffer,0,80*sizeof(char));
gets(buffer);
probably will see a different result
$ ./a.out
asdadsadasdsad
$ cat -v hello.txt
asdadsadasdsad^#^#^#^#^#^#^#^#^#^#^#^#^#^#
but the text is always writen once. the difference is how many bytes will be writen

Related

Difference between specifications of fread and fgets?

What is the difference between fread and fgets when reading in from a file?
I use the same fwrite statement, however when I use fgets to read in a .txt file it works as intended, but when I use fread() it does not.
I've switched from fgets/fputs to fread/fwrite when reading from and to a file. I've used fopen(rb/wb) to read in binary rather than standard characters. I understand that fread will get /0 Null bytes as well rather than just single lines.
//while (fgets(buff,1023,fpinput) != NULL) //read in from file
while (fread(buff, 1, 1023, fpinput) != 0) // read from file
I expect to read in from a file to a buffer, put the buffer in shared memory, and then have another process read from shared memory and write to a new file.
When I use fgets() it works as intended with .txt files, but when using fread it adds a single line from 300~ characters into the buffer with a new line. Can't for the life of me figure out why.
fgets will stop when encountering a newline. fread does not. So fgets is typically only useful for text files, while fread can be used for both text and binary files.
From the C11 standard:
7.21.7.2 The fgets function
The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.
7.21.8.1 The fread function
The fread function reads, into the array pointed to by ptr, up to nmemb elements whose size is specified by size, from the stream pointed to by stream. For each object, size calls are made to the fgetc function and the results stored, in the order read, in an array of unsigned char exactly overlaying the object. The file position indicator for the stream (if defined) is advanced by the number of characters successfully read. If an error occurs, the resulting value of the file position indicator for the stream is indeterminate. If a partial element is read, its value is indeterminate.
This snippet maybe will make things clearer for you. It just copies a file in chunks.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char ** argv)
{
if(argc != 3) {
printf("Usage: ./a.out src dst\n");
printf("Copies file src to dst\n");
exit(EXIT_SUCCESS);
}
const size_t chunk_size = 1024;
FILE *in, *out;
if(! (in = fopen(argv[1], "rb"))) exit(EXIT_FAILURE);
if(! (out = fopen(argv[2], "wb"))) exit(EXIT_FAILURE);
char * buffer;
if(! (buffer = malloc(chunk_size))) exit(EXIT_FAILURE);
size_t bytes_read;
do {
// fread returns the number of successfully read elements
bytes_read = fread(buffer, 1, chunk_size, in);
/* Insert any modifications you may */
/* want to do here */
// write bytes_read bytes from buffer to output file
if(fwrite(buffer, 1, bytes_read, out) != bytes_read) exit(EXIT_FAILURE);
// When we read less than chunk_size we are either done or an error has
// occured. This error is not handled in this program.
} while(bytes_read == chunk_size);
free(buffer);
fclose(out);
fclose(in);
}
You mentioned in a comment below that you wanted to use this for byteswapping. Well, you can just use the following snippet. Just insert it where indicated in code above.
for(int i=0; i < bytes_read - bytes_read%2; i+=2) {
char tmp = buffer[i];
buffer[i] = buffer[i+1];
buffer[i+1] = tmp;
}

Using information from an external file, How can I fill my array up correctly using fread?

I need to be able to make sure my array is correctly receiving values from the file card.raw through fread.
I am not confident about using arrays with pointers, so if anybody could help me with the theory here, it would be GREATLY appreciate it. Thanks in advance.
The code is supposed to take literally one block of size 512 bytes and stick it into the array. Then I am just using a debugger and printf to examine the arrays output.
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char* argv[])
{
//Size of EACH FAT JPEG in bytes
#define FILESIZE 512
unsigned char* buffer[FILESIZE];
///Step 1: Open jpeg
FILE* readfrom = fopen("card.raw", "rb");
if (readfrom == NULL)
{
printf("Could not open");
}
///Step 2: Find Beginning of JPEG. The first digits will be 255216255 Then 224 or 225
fread(&buffer, FILESIZE, 1, readfrom);
for(int x = 0; x < FILESIZE; x++)
{
printf("%d = %c\n", x, buffer[x]);
}
fclose(readfrom);
}
Use return values from input functions. fread() reports how many elements were read - code might not have read 512. Swap FILESIZE, 1 to detect the number of characters/bytes read.
// fread(&buffer, FILESIZE, 1, readfrom);
size_t count = fread(&buffer, 1, FILESIZE, readfrom);
Only print out up to the number of elements read. Recommend hexadecimal (and maybe decimal) output rather than character.
for(size_t x = 0; x < count; x++) {
// printf("%d = %c\n", x, buffer[x]);
printf("%3zu = %02X % 3u\n", x, buffer[x], buffer[x]);
}
If the fopen() failed, best to not continue with for() and fclose().
if (readfrom == NULL) {
printf("Could not open");
return -1;
}
The second parameter is size, in bytes, of each element to be read.
The third parameter is Number of elements each one with a size of the <second parameter> bytes.
So, swap your second and first parameters.
Replace unsigned char* buffer[FILESIZE]; with unsigned char buffer[FILESIZE];. For now, you have an array of unsigned char *, when you need unsigned char. Because buffer is already a pointer, you don't need to take its address. In fread call, replace &buffer with buffer.
It must go like this: fread(buffer, 1, FILESIZE, readfrom);
One more thing: add return with a specific error code after printf("Could not open");, because if file hasn't been open, you cannot read from it, can you? And add return 0; in the end of main.
And take your #define out of main.
Read more about fread here: http://www.cplusplus.com/reference/cstdio/fread/

Allocating memory from a file, then using fread and fwrite C

I'm having a bit of trouble getting my code to work, which is to open a file, count the number of characters in it, and then allocating that using malloc(). And then I am supposed to read the characters in from one file (mine contained "Hello World!") using fread(), and write them to a blank .txt file using fwrite.
My code so far is printing corrupted characters. I couldn't find any questions that were specific enough to my problem. If anyone could tell me what I'm doing wrong I'd appreciate it. I think it is specific to my fread and fwrite calls, but nothing I've tried works.
The code in question (not commented yet, sorry!):
#include <stdio.h>
#include <stdlib.h>
//initialized using ./a.out in.txt out.txt
int main(int argc, char *argv[])
{
FILE *fp;
int count, end;
char *memory;
char c[64];
fp = fopen(argv[1], "r");
if((fp) == NULL)
{
printf("Error: cannot open file.\n");
}
else
{
while((fgetc(fp))!= EOF)
{
count++;
}
memory = (char*)malloc(count);
c[64] = fread(memory, sizeof(char), 1, fp);
fclose(fp);
fp = fopen(argv[2], "w");
fwrite(c, sizeof(char), sizeof(c), fp);
fclose(fp);
free(memory);
}
return 0;
}
code have logical mistakes, as follow
Initialise variables int count= 0 , char c[64]= {0};
Type cast not required memory = malloc(count);
First you have counted number of char in file so Before reading again file rewind it by fseek(fp,0,SEEK_SET);
c[64] = fread(memory, sizeof(char), 1, fp); In this if you are reading single char, you should read complete file , To read complete file do fread(memory, 1, count, fp); and c[64] is out of bound and fread return the number of char successfully read .
fwrite(c, sizeof(char), sizeof(c), fp); In this you are writing complete char array to file but you have read only single variable in array which number of char read . So you are writing uninitialised char array to file. so you are getting corrupted character in file.
To write in file do fwrite(memory, 1, count, fp);
To solve problem ,avoid above error and read complete file in char array and then write.
Alright, there are a number of problems here, I'll start with the least bad:
memory = (char*)malloc(count);
Casting the return of malloc() is unnecessary and can potentially mask errors, for more info see here.
int count;
You never initialise count to anything. This is undefined behaviour and there is no guarantee it'll start at 0. It can start at random garbage left in memory. Same for end
c[64] = fread(memory, sizeof(char), 1, fp);
2 Problems here. c[64] is out of bounds for the array c since indexes start at 0, so the last element in the array is c[63]. sizeof(char) is defined to be 1, so use 1 instead. Further, fread() returns the amount of characters read, so not sure what you are trying to do with that value even.
fwrite(c, sizeof(char), sizeof(c), fp);
You're writing a complete uninitialised array to the file (=garbage)

fwrite and printing into an output file program

if i am writing into file with fwrite as follows
char buffer[3]={255,255,255,'\0'};
char buffer2[3]={0,0,0,'\0'};
fwrite(buffer, sizeof(char), sizeof(buffer), outputFile);
fwrite(buffer2, sizeof(char), sizeof(buffer2), outputFile);
what i am trying to understand is the third argument, sizeof(buffer)
my issue is that if the array has an appended '\0' nul character, does fwrite copy the nul character also into the file
also if i used a while loop to write into a file such as
int i=0;
while(i++<100){
fwrite(buffer, sizeof(char), sizeof(buffer), outputFile);
fwrite(buffer2, sizeof(char), sizeof(buffer2), outputFile);
}
what are the potential problems here directly to do with the nul character
also one more question , as i am having a problem with my program
int main (int argc, char *argv[]) {
// check that the types have the size i'm relying on here
assert (sizeof(bits8) == 1);
assert (sizeof(bits16) == 2);
assert (sizeof(bits32) == 4);
FILE *outputFile;
int squareSize;
outputFile = fopen(BMP_FILE, "wb");
assert ((outputFile!=NULL) && "Cannot open file");
writeHeader(outputFile);
printf ("Enter square size (must be a factor of %d): \n", SIZE);
scanf ("%d", &squareSize);
assert (SIZE % squareSize == 0);
char buffer[squareSize*BYTES_PER_PIXEL]; //white
char buffer2[squareSize*BYTES_PER_PIXEL]; //black
initialize(buffer, buffer2, squareSize);
int line=0;
int m=1;
while(line<SIZE){
if(line%squareSize==0&&m==1)
m=0;
else if(line%squareSize==1&&m==0)
m=1;
writeToFile(buffer,buffer2,m,outputFile,squareSize);
line+=squareSize;
printf("\nline is %d inside while loop ",line);
}
fclose(outputFile);
return EXIT_SUCCESS;
}
void writeHeader (FILE *file) {
assert(sizeof (bits8) == 1);
assert(sizeof (bits16) == 2);
assert(sizeof (bits32) == 4);
bits16 magicNumber = MAGIC_NUMBER;
fwrite (&magicNumber, sizeof magicNumber, 1, file);
bits32 fileSize = OFFSET + (SIZE * SIZE * BYTES_PER_PIXEL);
fwrite (&fileSize, sizeof fileSize, 1, file);
bits32 reserved = 0;
fwrite (&reserved, sizeof reserved, 1, file);
bits32 offset = OFFSET;
fwrite (&offset, sizeof offset, 1, file);
bits32 dibHeaderSize = DIB_HEADER_SIZE;
fwrite (&dibHeaderSize, sizeof dibHeaderSize, 1, file);
bits32 width = SIZE;
fwrite (&width, sizeof width, 1, file);
bits32 height = SIZE;
fwrite (&height, sizeof height, 1, file);
bits16 planes = NUMBER_PLANES;
fwrite (&planes, sizeof planes, 1, file);
bits16 bitsPerPixel = BITS_PER_PIXEL;
fwrite (&bitsPerPixel, sizeof bitsPerPixel, 1, file);
bits32 compression = NO_COMPRESSION;
fwrite (&compression, sizeof compression, 1, file);
bits32 imageSize = (SIZE * SIZE * BYTES_PER_PIXEL);
fwrite (&imageSize, sizeof imageSize, 1, file);
bits32 hResolution = PIX_PER_METRE;
fwrite (&hResolution, sizeof hResolution, 1, file);
bits32 vResolution = PIX_PER_METRE;
fwrite (&vResolution, sizeof vResolution, 1, file);
bits32 numColors = NUM_COLORS;
fwrite (&numColors, sizeof numColors, 1, file);
bits32 importantColors = NUM_COLORS;
fwrite (&importantColors, sizeof importantColors, 1, file);
}
void initialize(char *buffer, char*buffer2, int size){
//white for buffer 255,255,255 1 pixel
//black for buffer2 00,00,00 1 pixel
int buf = 255;
int buf2 = 0;
int i = 0;
while(i<size*3){
buffer[i]=buf;
buffer2[i]=buf2;
printf("\nbuffer 1 [i] is %c and i is %d\n",buffer[i],i);
printf("buffer 2 [i] is %c and i is %d\n",buffer2[i],i);
i++;
// printf("\nline ran %d times inside initialize loop ",i);
}
buffer[i]='\0';
buffer2[i]='\0';
printf("%s\n",buffer);
printf("%s",buffer2);
}
void writeToFile(char *buffer,char *buffer2, int m, FILE *file,
int squareSize){
int k = 0;
// printf("\nline ran %d times",line);
if(m==0){
while(k<(SIZE/squareSize)){
fwrite(buffer2, sizeof(char), sizeof(buffer2), file);
k+=1;
fwrite(buffer, sizeof(char), sizeof(buffer), file);
k+=1;
// printf("\nline ran %d times inside first if ",line);
}
}
else if(m==1){
while(k<(SIZE/squareSize)){
fwrite(buffer, sizeof(char), sizeof(buffer), file);
k+=1;
fwrite(buffer2, sizeof(char), sizeof(buffer2), file);
k+=1;
// printf("\nline ran %d times inside second else if",line);
}
}
}
the program is supposed to write to a file that is supposed to be a bmp file
the header write output function works fine
however i am having problem with the function initialize and the function writeToFile which i think has to do witht he nul pointer because i think fwrite is taking the nul pointer over as well and causing the bmp file to have the wrong information throw into it , also if i do remove teh nul character does fwrite produce problems by not stopping at the specified spot or does it stil copy correctly
i dont know what the problem is but the program is not writing in the order that i imagined
i have been at it ALL NIGHT and it still does not function correctly i am not sure where the problem is
the program is supposed to write into a 512 by 512 output file which is supposed to print out checkered black and white squares based on the input by user of a square which is a factor of 512
so that if the person chooses the input to be 256 , the program is supposed to divide the 512 by 512 space into 4 square with the first square being black then white, then white then black and etc
if the person choose 16 as the size of square in pixels, then i am supposed to divide the space into squares of 16 pixels sides ion the order of starting with black then white(across) next line above white then black all the way to the end
i think the problem is with my write to File function but i am not sure what the problem is, really confusing
hope you can help to give me some suggestions on how to deal with this problem
any help would be highly appreciated so that i can get this over and done with
The second argument of fwrite() is the size of each object, and the third argument is the number of objects. In your case, you tell it to write 4 objects of size 1, but here you could just write one object of size 4 just as easily.
"Nul characters" are irrelevant here, since they terminate strings, and fwrite() explicitly deals with binary objects, not strings. It'll write exactly what you give it to the file.
As an aside, a regular unqualified char can be (and often is) signed, rather than unsigned, so trying to stuff all those 255s into them may not be wise. unsigned char may be better for this.
In the writeToFile() function in your third block of code, this:
fwrite(buffer, sizeof(char), sizeof(buffer), file);
is a simple misunderstanding of how the sizeof operator works. In this context, buffer is not an array, it's a pointer to char that you have passed to the function. sizeof will therefore give you the size of a character pointer, usually 4 or 8 bytes, and that size will obviously be totally unrelated to the size of the buffer it points to. If char pointers are 8 bytes on your system, then sizeof(buffer) in this context will always evaluate to 8, regardless of whether you initially set up a 3 byte array, or a 4 byte array, or a 672 byte array.
To make what you want to do work in a function like this, you'll have to explicitly pass to the writeToFile() function the size of the buffer you created, and use that instead of sizeof.
fwrite and fread don't care at all about zero bytes. They simply write or read the number of bytes you ask for.
And note that buffer2 does not just have a '\0' appended but is in fact all '\0's since 0 and '\0' are identical in that context.
You don't need to zero-terminate your buffers since they aren't strings, they're just data and can contain zero-bytes within them.
Question: does fwrite copy the nul character also into the file?
Answer: The way you are calling it, the answer is "Yes". The third argument to the buffer is the number of objects that you wish to write to the stream.
Solution to your problem
You can change your variables
char buffer[3]={255,255,255,'\0'}; // This should be a compiler error/warning.
char buffer2[3]={0,0,0,'\0'}; // You have 4 items in {} for an array of size 3.
to
char buffer[3]={255,255,255};
char buffer2[3]={0,0,0};
You need a '\0' at the end of an array of char only if you want to treat the array as a null-terminated string. Since you are using the array to store only pixel values, you don't need to have the terminating null character in your array.
Potential pitfalls of not having the null character is that most functions that work with strings expect a terminating null character. They won't work with buffer or buffer2. Don't use:
Any of the standard string manipulation functions, such as strlen, strcpy.
printf("%s", buffer);.
and many other functions.
Considering your usage of those variable, I don't think you need to use them.

Need help to understand the output of this code

see my code is
#include <stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
int main(int argc, char**argv) {
unsigned char *message = NULL;
struct stat stp = { 0 };
stat("huffman.txt", &stp);
/*determine the size of data which is in file*/
int filesize = stp.st_size;
printf("\nFile size id %d\n", filesize);
FILE* original_fileptr = fopen("huffman.txt", "r");
message = malloc(filesize);
fread(message, 1, filesize, original_fileptr);
printf("\n\tEntered Message for Encode is %s= and length %d", message,strlen(message));
return 0;
}
here huffman.txt has size 20 bytes and following character are there
ά­SUä5Ñ®qøá"F„œ
output of this code is
File size id 20
Entered Message for Encode is ά­SUä5Ñ®qøá"F„œ= and length 21
now question is if size is 20 then why length is 21 ?
Because C doesn't have native strings, only arrays of characters, and there is a hidden, ubiquitous assumption that the last array member is a zero.
Since you violate that assumption by reading only 20 bytes into an array of 20 elements, with no regard to whether the final byte is zero, and then using string features like %s and strlen, you get essentially undefined behavior.
Getting an answer of 21 is pure luck; anything (far worse) could have happened.
Correct code could be something like this (assuming the file is a text file):
char * buf = calloc(filesize + 1, 1); /* yay, already zeroed! */
fread(buf, 1, filesize, fp);
printf("File contents: '%s'\nFile content size: %u.\n", buf, strlen(buf));
If you're reading arbitrary ("binary") files, this will generally not produce the expected result (unless you know what to expect).

Resources