fread() puts weird things into char array - c

I have a file that I want to be read from and printed out to the screen. I'm using XCode as my IDE. Here is my code...
fp=fopen(x, "r");
char content[102];
fread(content, 1, 100, fp);
printf("%s\n", content);
The content of the file is "Bacon!" What it prints out is \254\226\325k\254\226\234.
I have Googled all over for this answer, but the documentation for file I/O in C seems to be sparse, and what little there is is not very clear. (To me at least...)
EDIT: I switched to just reading, not appending and reading, and switched the two middle arguments in fread(). Now it prints out Bacon!\320H\320 What do these things mean? Things as in backslash number number number or letter. I also switched the way to print it out as suggested.

You are opening the file for appending and reading. You should be opening it for reading, or moving your read pointer to the place from which you are going to read (the beginning, I assume).
FILE *fp = fopen(x, "r");
or
FILE *fp = fopen(x, "a+");
rewind(fp);
Also, fread(...) does not zero-terminate your string, so you should terminate it before printing:
size_t len = fread(content, 1, 100, fp);
content[len] = '\0';
printf("%s\n", content);

I suppose, you meant this:
printf("%s\n", content);

Maybe:
fp = fopen(x, "a+");
if(fp)
{
char content[102];
memset(content, 0 , 102);
// arguments are swapped.
// See : http://www.cplusplus.com/reference/clibrary/cstdio/fread/
// You want to read 1 byte, 100 times
fread(content, 1, 100, fp);
printf("%s\n", content);
}

A possible reason is that you do not terminate the data you read, so printf prints the buffer until it finds a string terminator.

Related

writing multiple lines back to a file, wrong file length

I want to get the a multiline text file's content, and put it back to the file.
However, I have an issue with the file length.
The null terminator (0) that I add is after some strange characters.
Something wrong with my f_length ?
Edit : If I set the line-endings of my file to Unix (LF), I don't have the issue. So it seems that my code is incompatible with Windows line endings. How can I account for Windows text files ?
int main()
{
FILE *fp = NULL;
int f_length;
char *buffer = NULL;
size_t size = 0;
fp = fopen(FILENAME, "r+");
fseek(fp, 0, SEEK_END);
f_length = ftell(fp);
rewind(fp);
buffer = malloc((f_length + 1) * sizeof(*buffer));
fread(buffer, f_length, 1, fp);
buffer[f_length] = 0;
printf("%s\n", buffer);
fp = fopen(FILENAME, "w+");
fputs(buffer, fp);
fclose(fp);
return 0;
}
Use fp = fopen(FILENAME, "rb+"); instead. For text files, you'll have newline characters replaced while reading (you've already noticed that in comments). In some cases, new format is shorter ("\r" or "\n" while the file itself contains "\r\n"), so f_length will be bigger than the actual data read.
Or you can use line-by-line reading functions, they are made for text-mode files.
You are assuming the size of the file on disk is going to be equal to the number of bytes you will read. That is a valid assumption for a clean, binary file. It is not a valid assumption for a text file.
I'd suggest using the return value from fread instead of f_length as it reports the number of objects you actually read after any required read processing. You'll need to adjust your fread parameters to read 1-byte sized objects.
regarding:
buffer[f_length] = 0;
This is placing the '0' way too far into the buffer. this is why you see garbage characters. Much better to capture the returned value from the call to fread() and set the '0' using:
buffer[ <returnedValue> ] = '\0';

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)

C splitting character array read from a file by \n (newline character), strange output

I am reading a raw text file into a character array and then I want to split the data line by line based on "\n". My code is attached, but I get very strange output.
INPUT FILE is a .txt file created with VIM on Windows, and it looks like:
london
manchester
britain
...
CODE (ignoring some var declarations):
....
char * buffer = 0;
long length;
fl = fopen ("file.txt", "r");
if (fl){
fseek (fl, 0, SEEK_END);
length = ftell (fl);
fseek (fl, 0, SEEK_SET);
buffer = malloc (length);
if (buffer){
fread (buffer, 1, length, fl);
}
fclose (fl);
printf(buffer)
}else{
printf("data file not found");
return -1;
}
char str[80] = "london\nmanchester\nbritain";
char* entity = strtok(buffer, "\n"); //LINE-A, replacing 'buffer' with 'str' the output is correct.
while (entity != NULL) {
printf("%s\n", entity); //this prints strange output as shown below
entity = strtok(NULL, "\n");
}
....
OUTPUT:
ondon
anchester
ritain
The first character is always missing.
However, if I replace "buffer" with "str" the declared character array with the same content as the file everything works as expected.
I do not understand why I am getting this error. Any advice please.
Mnay thanks!
This may be related to the fact that you aren't terminating your string buffer. I'm unable to produce your exact problem but I do get unexpected extra characters in the output. Amend the relevant lines of your code as follows and see if that helps:
buffer = malloc(length + 1);
if (buffer) {
fread(buffer, sizeof(char), length, fl);
buffer[length] = '\0';
}
fclose(fl);
If that doesn't solve your problem, you might have some weird (invisible) control characters in your text file. Try creating a brand new one and see if the problem still occurs.

Read contents of a file into string while skipping first two lines

I'm trying to read the contents of a file into one string without reading in the first two lines.
Right now I have:
char* LoadDocument(char* name) {
char* buffer = 0;
long length;
FILE* f = fopen(name, "r");
if(f) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
buffer = malloc(length);
if (buffer) {
fgets (buffer, 100, f);
}
fclose (f);
}
return buffer;
}
But I'm not sure how to skip the first two lines. Also, it appears my malloc is insufficient to hold the whole file here, because it's not getting the whole file.
One solution is to read the complete file into the buffer, manually find the end of the second line, and move the remaining data to the beginning of the buffer.
Also, don't forget to add the string terminator, if you want to use the buffer as a string.
The easiest way is just to read two lines before your "real" reading begins:
char line[1024];
fgets(line, sizeof line, f);
fgets(line, sizeof line, f);
You should probably error-check this too, since the file might be shorter in which case you won't get the expected results. Also the length might be too short. If you really want to support any length, read single characters until you find the end of line, twice.
Your final fgets() should probably be a fread() call, to read the entire rest of the file. You might want to compensate for the lost length due to the initial skipping, too.

C: use fwrite to write char to different line

I have to write to a file as follows:
A
B
C
D
...
Each character of the alphabet needs to be written to different line in the file. I have the following program which writes characters one after another:
FILE* fp;
fp = fopen("file1","a+");
int i;
char ch= 'A';
for(i=0; i<26; i++){
fwrite(&ch, sizeof(char), 1, fp);
ch++;
}
fclose(fp);
How should I change the above program to write each character to a new line. (I tried writing "\n" after each character, but when I view the file using VI editor or ghex tool, I see extra characters; I am looking for a way so that vi editor will show file exactly as shown above).
I tried using the following after first fwrite:
fwrite("\n", sizeof("\n"), 1, fp);
Thanks.
fwrite("\n", sizeof("\n"), 1, fp);
should be
fwrite("\n", sizeof(char), 1, fp);
Otherwise, you are writing an extra \0 that is part of zero-termination of your "\n" string constant (sizeof("\n") is two, not one).
What "extra characters" do you see? You do realize that the "a+" parameter to fopen opens the file for appending, so that you're writing to the end of the file. Did you perhaps mean "w+", which will overwrite the file?
You could use:
fputc((int)ch, fp);
fputc((int)'\n', fp);
Or even fprintf(fp, "%c\n", ch);

Resources