Saving an integer array to a file in C - c

I've been trying to write the contents of an integer array to a file in C. I've been using the code below to do so.
int etData [600];
int i;
int size = sizeof(char);
for (i=0; i<600; i++)
{
etData[i] = analog_et(5);
}
FILE *f = fopen("/home/root/Documents/KISS/Default User/Launch Code/data/data", "w");
fwrite(etData, size, sizeof(etData), f);
fclose(f);
analog_et is a function that returns an integer value from a sensor. Whenever I run this code, a mess of ASCII characters is written to the file. I believe this is to blame on the fact that I am passing fwrite an element size sizeof(char) - however, whenever I attempt to pass a value larger than one byte, nothing is written to the file, and fwrite fails to return a non-zero value.
I've looked for a function in stdio that would be better suited to this purpose but can't find one. Any suggestions on how to fix this issue? Thanks!

If you want a textual representation of your data (in that case the file can be opened with a text editor), you cannot user fwrite but you need to use fprintf. Latter does basically is the same thing as printf, but instead of being displayed, the data is written into a text file.
You probably want this:
...
FILE *f = fopen("/home/root/Documents/KISS/Default User/Launch Code/data/data", "w");
for (i=0; i<600; i++)
{
fprintf("%d\n", etData[i]);
}
...

Related

Codification, write an integer in a file

I am doing a coding task in the C language, I go well until the part of reading the symbol and assign the corresponding code according to a table. I must concatenate several codes until they reach 32 bits in length, to accomplish this I must write them in a file.
This method of writing to file is giving me a lot of problems, I'm trying to do it with the fputc() function.
I can not change the declaration of the function because they request it for the homework.
I create a mask to be able to write the integer by bytes because they also suggest that the teachers of the course.
The program with that code works but when I see the file with a binary viewer it only prints zero.
Any idea of what I'm doing wrong?
Thanks!
void write_int(FILE* fp, unsigned int buffer, int nbytes){
if ( (nbytes <= sizeof(int)) && (nbytes>=0) ){
unsigned int aux;
int i;
for (i=4; i>(4-nbytes) ; i--){
aux = buffer & new_mask( ((i*8)-1),((i-1)*8));
fputc(aux,fp)
}
fputc('\n',fp);
}else{
printf("nbytes out of range");
}
}
fputc is used to write one ASCII-character into a file.
int fputc(int, FILE*) //this int is converted to unsigned before going to the file(your bits are probably being messed up here)
1- solution: Open this file in binary mode and write using fwrite
fp = fopen("filename", "wb+");
fwrite(buffer, 4, 1, fp);
*since integers on most computers have 32bits(4bytes) this should write your whole 32 bits at once in a binary file
2- solution: Assuming that you can't open the file in binary mode inside this function... you could simply write 4chars usgin fprintf.
int fprintf(FILE*, format, ....);
*note: it's hard to help more than this, because it's not clear what is nature of these symbols.
ex: binary stream, integer number, ascii, utf, etc

Unable to write shell history to a text file

I'm currently writing a shell with basic functions in C, operating through Unix. I'm having difficulty transferring an array of history commands to a text file.
History is stored as a pointer to an array, with a capacity of 20 as not to over-complicate things. I got the basis of the method online so I've tried to tailor it to my needs, however it just feeds a bunch of weird characters to the text file.
Does anyone know why this may be happening?/What I could do to fix it?
I'm also not sure if the for loop is necessary.
Thanks in advance!
char *history[2];
void save(char ** history)
{
FILE *f;
f = fopen("history.txt", "w+");
for(int i = 0; i < 20; i++)
{
fwrite (history, sizeof(history[i]), sizeof(history)/sizeof(history[i]), f);
}
fclose(f);
}
history
is a char **, which is a pointertype.
history[i]
is char*, so still a pointertype
sizeof(history)/sizeof(history[i])
always returns one, since all pointertypes shall have the same size.
So your write statement will print sizeof(< anypointer >) random characters.
Solution
for(int i = 0; i < 20; i++){
fwrite (history[i], sizeof(*history[i]), strlen(history[i]) + 1, f);
}
Notice: This will include the '\0' for each string.
Notice: This will write the internal state into the file, so you should consider to open it in binary-mode or to use:
fputs(history[i], f);
fputc('\n', f); /*or anything similar*/

Getting garbage value in structure when reading from file

I have a text file like this
987jgkfl
12358ldjkdju
7579jngj
8uuujkl
09698fjfj
I have a structure like this
struct emprec
{
int empid;
int todo;
char name[20];
};
I write the values of the struct into file like this
fd = fopen("/home/tarun/Desktop/test34.txt","a+");
fprintf(fd,"%d",temp2.empid);
fprintf(fd,"%s",temp2.name);
count++;
fclose(fd);
But when i read from the file i am getting the garbage value
while(i<=count)
{
fread(&temp5,sizeof(temp5),1,fd);
//fscanf(fd,"%d,%s",&temp5.empid,temp5.name);
//int k = strlen(temp5.name);
//printf("Value of k is %d\n",k);
//temp5.name[7]= '\0';
//fread(&temp5.empid,sizeof(temp5.empid),1,fd);
//fread(temp5.name,20,1,fd);
printf("\n%d %s",temp5.empid,temp5.name);
i++;
}
fclose(fd);
Please tell me where am i going wrong
Like say nemetroid :
You're writing a textual representation (with
fptrinf) of your struct but attempting to read a binary representation
(with fread).
For example, suppose you want write an int in a file. By doing like this :
fd = fopen("file","a+");
fprintf(fd,"%d",42);
You will write the character '4' and the character '2'. In ASCII, '4' is 0x34 and '2' is 0x32.
If you want to read that file and try to put it in an 4 bytes integer by doing like this :
int a = 0;
fread(&a,sizeof(a),1,fd);
The variable 'a' will contain the data on the file :
a = 0x00003234
And not 42 (0x0000002a) as you expect.
There were some calls that was missing from your code:
fflush()
Used to flush the file's buffer, you have to call this if you performed writes to the file and now you want to read
fseek
Used to set the file position indicator. In your case, the file position indicator was at the end of the file. Use fseek() to set the file position to where you started writing and than start reading.
fscanf function corresponds to fprintf. fread corresponds to fwrite. It means if you want to dump the structure using fprintf, then read it using fscanf. if you want to read the structure using fread then dump it using fwrite. Referring manpages of these functions should help.

fread() reads from current file and old file

When I use this code
FILE *f = fopen(file, "rb");
const char *d;
if (f!=NULL) {
static char c[100000];
fread(c, sizeof(char), 10000000, f);
d = c;
fclose(f);
return d;
}
else{
/*
char *ff = f;
perror(ff);
*/
d = "Error";
fclose(f);
return d;
}
to read from a file that has text like this
This
Is a test
it reads it fine. However, if I open a different file that has this text
Test
it will read something like
Test Is a test
Why does it combine both into one when the file is closed?
I put this now, but I still get the same results
if (f!=NULL) {
fread(c, sizeof(c), len, f);
d = c;
fclose(f);
c[99999] = '\0';
return d;
}
Looks like there are characters left in your array from the last read. You should null terminate the string before returning, fread() won't do this for you.
You've got some other issues too, such as the character limit for fread() being way bigger than your buffer size.
Unless you really need c for this, you should think about using c++ or even some other language with more sophisticated file and text processing libraries, it would make your life easier.
fread() doesn't NUL-terminate the buffer which it reads to. If the second read is shorter than the first one, the rest of the first which is not overwritten will remain there. And anyway your program invokes undefined behavior at so many places it's not even funny.
For example, this:
static char c[100000];
fread(c, sizeof(char), 10000000, f);
is most likely a typo - you're allowing fread() to read 100 times more data than the size of the buffer. That's why you should always (I mean, A-L-W-A-Y-S) use the sizeof() operator and the size of the array element instead of its type. Also, sizeof(char) is always 1, don't spell out redundant data:
fread(c, sizeof(c), 1, f);
You are reading the data into a static buffer, and you don't terminate the string when you're done.
Since c is static, it is zero initialized. You partly overwrite that with the data from the fread() call.
So, you should use the returned value from fread() and set c[len] to '\0'.

Simple count how many integers are in file in C

Im currently learning C through random maths questions and have hit a wall. Im trying to read in 1000 digits to an array. But without specifiying the size of an array first i cant do that.
My Answer was to count how many integers there are in the file then set that as the size of the array.
However my program returns 4200396 instead of 1000 like i hoped.
Not sure whats going on.
my code: EDIT
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
FILE* fp;
const char filename[] = "test.txt";
char ch;
int count = 0;
fp = fopen(filename, "r");
if( fp == NULL )
{
printf( "Cannot open file: %s\n", filename);
exit(8);
}
do
{
ch = fgetc (fp);
count++;
}while (ch != EOF);
fclose(fp);
printf("Text file contains: %d\n", count);
return EXIT_SUCCESS;
}
test.txt file:
731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511
125406987471585238630507156932909632952274430435576689664895044524452316173185640309871112172238311362229893423380308135336276614282806444486645238749
303589072962904915604407723907138105158593079608667017242712188399879790879227492190169972088809377665727333001053367881220235421809751254540594752243
525849077116705560136048395864467063244157221553975369781797784617406495514929086256932197846862248283972241375657056057490261407972968652414535100474
821663704844031998900088952434506585412275886668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912883142607690042
242190226710556263211111093705442175069416589604080719840385096245544436298123098787992724428490918884580156166097919133875499200524063689912560717606
0588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
Any help would be great.
You forgot to initialize count, so it contains random garbage.
int count = 0;
(But note that with this change it's still not going to work, since %d in a scanf format means read as many digits as you find rather than read a single digit.)
Turn on your compiler's warnings (-Wall), it will tell you that you didn't initialize count, which is a problem: it could contain absolutely anything when your program starts.
So initialize it:
int count = 0;
The other problem is that the scanfs won't do what you want, at all. %d will match a series of digits (a number), not an individual digit. If you do want to do your counting like that, use %c to read individual characters.
Another approach typically used (as long as you know the file isn't being updated) is to use fseek/ftell to seek to the end of the file, get the position (wich will tell you its size), then seek back to the start.
The fastest approach though would be to use stat or fstat to get the file size information from the filesystem.
If you want number of digits thin you tave to do it char-by-char e.g:
while (isdigit(fgetc(file_decriptor))
count++;
Look up fgetc, getc and scanf in manpages, you don't seem to understand whats going on in your code.
The way C initializes values is not specified. Most of the time it's garbage. Your count variable it's not initialized, so it mostly have a huge value like 1243435, try int count = 0.

Resources