C fwrite() writes amount of characters doubled - c

When I use this code
FILE *f = fopen(file, "wb");
fflush(f);
if (f==NULL) {
//perror(f);
return 0;
}
else{
fwrite(text, sizeof(char), strlen(text), f);
int i = fprintf(f, "%s", text);
if (i>0) {
fclose(f);
return 1;
}
(text is const char text[1024000], which is set as one of the arguments in the function)
if I write
This is a test
This is a test
to test if it can write multiple lines, it writes this
This is a test
This is a testThis is a test
This is a test
why do I get this weird behavior?

You're writing twice:
fwrite(text, sizeof(char), strlen(text), f);
int i = fprintf(f, "%s", text);
Pick one

These two lines write "text" twice. They do same thing.
fwrite(text, sizeof(char), strlen(text), f);
int i = fprintf(f, "%s", text);
The only difference is fprintf write one more byte '\0' than fwrite.

Related

Why fread reads bytes in a file altough I don't indicate what byte is next to read?

I have this code that copy a file in a destination
#include <stdio.h>
int main(void)
{
FILE *input = fopen("input.txt", "r");
if (input == NULL)
{
return 1;
}
FILE *output = fopen("output.txt", "w");
if (output == NULL)
{
fclose(input);
return 1;
}
char c;
while (fread(&c, sizeof(char), 1, input))
{
fwrite(&c, sizeof(char), 1, output);
}
fclose(input);
fclose(output);
}
The program works but i don't understand how, in the while loop, fread/fwrite can know what is the next byte to use without I say it.

Write and read from some file

I have a similar code.
#include <stdio.h>
int main() {
FILE* file = fopen("file.txt", "w+");
fputc('A', file);
fflush(file);
char buff;
fscanf(file, "%s", &buff);
printf("read data: %s", &buff);
fclose(file);
return 0;
}
I want without close file read written data. But in buff not exist data.
Why?
If i close file after writing and then read all worked.
You should use rewind(file) to set the position indicator associated with the file stream to the beginning of the file.
Your example, working fine:
#include <stdio.h>
int main() {
FILE* file = fopen("file.txt", "w+");
fputc('A', file);
fflush(file);
rewind (file);
char buff [80];
fscanf(file, "%s", buff);
printf("read data: %s", buff);
fclose(file);
return 0;
}
Rewind back to the beginning of the file:
rewind(file);

C Why can't my fgets() read line properly when writing with \n after words

This is a bit difficult to articulate but what I would like is for my commented out fprintf function to be commented in and my other two print functions commented out (In my add_to_white_list function).
However, when I write to the file in that way (with the \n after the word) something goes wrong with my fgets line reader in the remove_from_white_list function. In debugging my fgets reads the first line and then seems to be blank after.
This if very confusing to me because everything mostly works as is and there are still newline characters after all my words except for the last word in the file.
void add_to_white_list(char* ip) {
FILE *fp;
fp = fopen("../app/whitelist.txt", "r+");
if (!(getc(fp) < 0)) {
fseek(fp, 1, SEEK_END);
fputs("\n", fp);
}
fprintf(fp, "%s", ip);
//fprintf(fp, "%s\n", ip);
fclose(fp);
}
void remove_from_white_list(char* ip) {
FILE *fp;
FILE *fp_temp;
fp = fopen("../app/whitelist.txt", "r");
fp_temp = fopen("../app/temp.txt", "w+");
char buff[255];
int matched = 0;
while (fgets(buff, 255, fp) != NULL) {
strip(buff);
if (!(strcmp(buff, ip) == 0)) {
fprintf(fp_temp, "%s\n", buff);
} else {
matched = 1;
}
}
fclose(fp);
fclose(fp_temp);
if (matched == 0) {
printf("Please supply an ip address that is currently listed on the whitelist\n");
} else {
rename("../app/temp.txt", "../app/whitelist.txt");
}
}
*I didn't include my strip function but it removes \n
This may not fix your problem but you can simplify add_to_white_list to:
void add_to_white_list(char* ip) {
FILE *fp = fopen("../app/whitelist.txt", "a");
if ( fp != NULL )
{
fprintf(fp, "%s\n", ip);
fclose(fp);
}
}

fread position cursor does not seem to advance as expected

I'm trying to dynamically realloc memory for a file being read one character at a time. It is not printing the buffer character by character. It looks like the fread function is not advancing 1 character at a time.
int main() {
FILE *fp;
char *newBuffer;
char *buffer = malloc(sizeof(char));
int count = 0;
/* Open file for both reading and writing */
fp = fopen("test.txt", "r");
if (!fp) {
exit(99);
}
/* Seek to the beginning of the file */
fseek(fp, SEEK_SET, 0);
/* Read into memory and display the buffer as its read */
while (1) {
newBuffer = (char*)realloc(buffer, (sizeof(char) * (++count)));
if (newBuffer) {
buffer = newBuffer;
buffer += (count - 1);
fread(buffer, sizeof(char), 1, fp);
if (feof(fp)) {
buffer = newBuffer;
break;
}
buffer = newBuffer;
printf(" %s\n", buffer);
} else {
// realloc failed
free(buffer);
exit(1);
}
}
fclose(fp);
free(newBuffer);
return(0);
}
You do not null terminate the buffer before using it as a string in printf, this is a problem.
Note that you can simplify or improve the code in various ways:
no need to fseek(fp, SEEK_SET, 0); after fopen, the FILE is already at the starting position. Note that you interverted the arguments to fseek: it should be fseek(fp, 0L, SEEK_SET); but you are lucky SEEK_SET is #defined as 0.
reading one byte from the file is much simpler with getc than fread(buffer, sizeof(char), 1, fp);. It allows for a simpler and better test for end of file. Using feof() only works in your example because you only attempt to read a single byte.
no need for the initial malloc, set buffer toNULL.reallocacceptsNULLand behaves likemallocwith such as argument,freeaccepts aNULL` argument and does nothing.
do not cast the return value of malloc, nor realloc.
sizeof(char) is 1 by definition: either use sizeof(*buffer) or elide the sizeof completely.
do not parenthesize the return expression.
the prototype for main without arguments is int main(void)
Here is a simpler version:
int main(void) {
FILE *fp;
char *newBuffer;
char *buffer = NULL;
int count = 0, c;
/* Open file for both reading */
fp = fopen("test.txt", "r");
if (!fp) {
exit(99);
}
/* Read into memory and display the buffer read */
while ((c = getc(fp)) != EOF) {
newBuffer = realloc(buffer, count + 2);
if (newBuffer) {
buffer = newBuffer;
buffer[count++] = c;
buffer[count] = '\0';
printf(" %s\n", buffer);
} else {
// realloc failed
fclose(fp);
free(buffer);
exit(1);
}
}
fclose(fp);
free(buffer);
return 0;
}
Your printf(" %s\n", buffer); expects buffer to end with a '\0' (null) character. Your code doesn't provide the required null.

Writing and printing strings from an array in a file in C

I have an array being written to the file, but then I need a way to print that same information out from the file when I call the function. The first part of the code is in the main function, and the second is a second function that prints out the values that are supposed to be from the file (fp).
fp = fopen("Grue.txt", "wb");
for(i = 0; i < 5; i++)
{
char newLine[3] = {"\n"};
char space[2] = {" "};
fwrite(array[i].name, strlen(array[i].name), sizeof(char), fp);
fwrite(space, strlen(space), sizeof(char), fp);
fwrite(array[i].height, strlen(array[i].height), sizeof(char), fp);
fwrite(space, strlen(space), sizeof(char), fp);
fwrite(array[i].weight, strlen(array[i].weight), sizeof(char), fp);
fwrite(space, strlen(space), sizeof(char), fp);
fwrite(array[i].items, strlen(array[i].items), sizeof(char), fp);
fwrite(newLine, strlen(newLine), sizeof(char), fp);
}
fclose(fp);
fp = fopen("Grue.txt", "rb");
PrintAGrue(fp);
void PrintAGrue(FILE *a)
{
// create End of file character onto the array being saved,
int i;
char n;
char h;
char w;
char m;
for (i=0; i<5; i++)
{
n = fread(a[i].name, strlen(array[i].name, sizeof(char), a);
h = fread(array[i].height, strlen(array[i].height, sizeof(char), a);
w = fread(array[i].weight, strlen(array[i].weight, sizeof(char), a);
m = fread(array[i].items, strlen(array[i].items, sizeof(char), a);
printf("This grue is called %s and is %s feet tall, and weighs %s pounds, and has eaten %s things.", n, h, w, m);
}
}
In PrintAGrue, it looks like you're using strlen() calls to decide how much data to read -- but how
can you know the size of the string before you've read it? (Also, the parentheses don't look balanced...)
Perhaps your file format should explicitly include a length field for each string -- then you
can do one fread to find the string size, and another to actually read the string.

Resources