fprintf isn't writing to file - c

I am trying to use the following C code to print out an array that I have passed in. It should output the text in hexadecimal format one on each line and I have no problems opening the file. When I first wrote it, I had no problems with it working I opened the output file and my array was there. I changed the fileOutName parameter and now I can't get it to print out anything I have tried changing it back and to a few other things and nothing seems to work. Also when I debug it seems like pOutfile is a bad pointer, but like I said it still creates the file it just won't write anything in it. Any help would be appreciated. Thanks
printoutput(int output[], char * fileOutName){
int i = 0;
FILE * pOutfile;
pOutfile = fopen( fileOutName, "w" );
while(output[i] != 0){
fprintf( pOutfile, "0x%0.4X\n", output[i] );
i++;
}
}

Always clean up after yourself. You're missing an fclose(pOutfile).

It should output the text in hexadecimal format one on each line ...
This line
fprintf( pOutfile, "0x%0.4X\n", 5 );
always formats the same number - 5. It probably should be
fprintf( pOutfile, "0x%0.4X\n", output[i] );

You're counting on the element beyond the bounds of the array to be 0, which may not be the case unless you're explicitly setting it. If you are, that's okay. Usually, pass arrays along with their size; this is safer, easier to read, and more portable.
printoutput(int output[], int size, char * fileOutName){
int i=0;
FILE * pOutfile;
pOutfile = fopen( fileOutName, "w" );
while(i!=size){
fprintf( pOutfile, "0x%0.4X\n", output[i] );
++i;
}
fclose(pOutfile)
}
Also, I HIGHLY recommend getting used to using the pre-increment operator instead of post-increment. In situations like this, it probably won't make a difference, but for large inputs or complex types, it can reduce execution time. Hence, ++i instead of i++.

Related

Saving an integer array to a file in 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]);
}
...

allocation with char pointer

I am beginner.I have a file which has lines like MONSTER,ERRTU,14,2 . when i tried to read the lines and store them into a dynamic memory allocated array. it seems like it worked at first but then when i tried to print the elements of it later , it doesnt work properly.Is it about using char * ? How can I fix this problem?
here my code is;
char *lines_ptr;
line_ptr=(char *)malloc(line*(sizeof(char)*100));
int i=0;
if (fptr==NULL){
printf("file could not be opened.");
}
else{
//line=number of lines
while(!feof(fptr)){
for(i=0;i<line;i++){
fscanf(fptr,"%s",lines_ptr+i);
printf("%s\n",(lines_ptr+i));
}
}
printf("%s",(lines_ptr));//this part shows me i did something wrong.
}
here is my output;
HERO,DRIZZT,8,3
HERO,CATTIE,6,3
HERO,BRUENOR,10,1
HERO,WULFGAR,12,4
MONSTER,TROLL,4,3
MONSTER,GOBLIN,1,3
MONSTER,UNDEAD,1,1
MONSTER,VERMIN,3,2
MONSTER,MINDFLAYER,10,2
MONSTER,ERRTU,14,2
HHHHMMMMMMONSTER,ERRTU,14,2
why does it happen?
HHHHMMMMMMONSTER,ERRTU,14,2 //why does it happen?
What you do is as follows.
You read to the line buffer, but every time you move the beginning of the text by 1 character.
So when you come back and print beginning of the buffer you will get all the first characters of all previously read lines plus last read line.
you incorrectly use "line_ptr" (and so many other stuff ...).
From what I understand, it's seem you whant to load the entire file into "line_ptr", each file's line being in "line_ptr[i]".
If that so, then I advise you to take your time and do really simple code, and after, make it more complicated.
For instance, dont use malloc : with your current code, it's useless anyway.
Let's say you have a file with NB_LINE line at maximum, each line having NB_MAX_CHAR character at maximum.
#define NB_LINE_MAX 50
#define NB_CHAR_MAX 100
char lines[NB_LINE_MAX][NB_CHAR_MAX];
size_t nbLines = 0;
for (nbLines = 0; fgets(lines[nbLines], NB_CHAR_MAX, fptr); ++nbLines) {
// Nothing to do, fgets do it for us
}
if (!feof(fptr)) {
// problem while reading :/
}
printf("Test :\");
for (size_t i = 0; i < nbLines; ++i) {
printf("%d : %s", i, lines[i]);
}
Does this code work ? If yes, try to improove it by removing NB_LINE_MAX first (then you can have at many line you want in your file, not only 50) and after, try to remove NB_CHAR_MAX (then you can have a line without char limitation).
Misc remark :
sizeof(char) is alway 1, always. So you can delete it from your malloc.
fscanf(fptr,"%s",lines_ptr+i) is dangerous. %s will read at many char it want, so if he read 500 char but lines_ptr can only hold 100 of them, it will write somewhere not good, and you will probably have SIGSEV runtime crash.
while(!feof(fptr)) already say by another, but it's note how you use feof.
There are some mistakes you are doing.First look carefully what you are messing with in the picture.Suppose there are two line in the input hello and world,while taking the first input line_ptr starts from 0,so it will store hello from 0 to 4 but in second line line_ptr is incremented to 1 so it will store world from 1 to 5 and this will go on if more lines are there.
NOTE: Always check the return value of scanf() or fscanf()
For taking line as a input in c, you should use Array of pointers like char *lineptr[MAXLINE];
int readline(char* lineptr[])
{
char line[1000];
for(i=0;i<MAXLINE;i++){
if(fscanf(stdin,"%s",line)){
char *temp=malloc((strlen(line)+1)*sizeof(char));
strcpy(temp,line);
lineptr[i]=temp;
}
}
return i;
}
This function will read a line in a variable line, then it will allocate memory for that line in temp and lineptr[i] will point to that new line.It returns number of lines read.
the following proposed code:
always reads the whole line from the file
properly checks for errors
properly places the read in data in the 'malloc'd array
eliminates the clutter from the code
eliminates the use of a 'magic' number in the code
and now the proposed code
if ( !fptr )
{
perror( "file could not be opened." );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
#define MAX_LINE_LEN 100
//size_t line=number of lines
char *line_ptr = malloc( line * MAX_LINE_LEN ));
if( !line_ptr )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
size_t i = 0;
// Note: '%[^\n]' reads to end of line, but not the newline char
// AND appends a NUL byte to the end of the input
// '%*c' reads and discards the newline char
// Note: using the '%*c' requires the last line in the file ends with a newline char
// otherwise the last call to `fscanf()` will 'hang' looking for the final newline
while( i < lines && 1 == fscanf(fptr,"%[^\n]%*c", line_ptr+(MAX_LINE_LEN*i) ) )
{
printf( "%s\n", line_ptr+(MAX_LINE_LEN*i) );
i++;
}

Inserting 400 numbers in a text file

I am trying to write numbers from 1, up to 400 in a text file. I am using the code below, which is running without any errors, but the file is being left empty.
Any help would be appreciated.
#include <stdio.h>
int main(void)
{
FILE *filePointer;
filePointer = fopen("file.txt","w");
int i;
for(i=0; i > 400; i++)
{
fputs("%d, ",i,filePointer);
}
fclose(filePointer);
return(0);
}
No, there's no way that compiled without some serious-sounding warnings at least.
You're using fputs() as if it were fprintf(), passing it an integer instead of a FILE pointer (which the compiler should not allow) and an extra argument (which the compiler should not allow).
Also your for loop is broken. The middle part is an expression that should be true for as long as the loop should run, not the other way around.
You meant:
for(i = 0; i < 400; ++i)
{
fprintf(filePointer, "%d, ", i);
}
Also, you should check that the file really did open before assuming it did. I/O can fail.
Apart from the fputs() usage, the problem is:
for(i=0; i > 400; i++)
If you initialize a variable with zero and perform a loop as long as it's greater than 400, that won't last too long.
The fputs syntax seem wrong. I think it is:
int fputs(const char *str, FILE *stream)
Pick #unwind's approach (as mentioned above) but if you still want to use fputs then your fputs line should be expanded into 3 lines:
char temp[4]; // String to store 3-digit number + '\0'
sprintf(temp, "%d, ", i); // Prepare a string for a given number
fputs(temp, filePointer); // Write the string to the file
This should work. #happycoding :)
PS: You seem to be following a bit C++ standard in declaring a variable anywhere. It is not pure C. #justsaying

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.

Writing to a file(fprintf)

Im trying to add some bindings to ARP table in Linux, in C. Im opening a file with "a" (append, right?) and then trying to write some addresses, but I always get segmentation fault. I believe there is something wrong with ARP_table[i].IPaddr, ARP_table[i].MACaddr, ARP_table[i].ARPstatus
struct ARP_entry
{
char IPaddr[16];
char MACaddr[18];
char ARPstatus;
int timec;
};
static struct ARP_entry ARP_table[ARP_table_vel];
void copyZIS()
{
int i=0;
const char filename[] = "/proc/net/arp";
FILE *file = fopen(filename, "a");
for (i; i< i+j; i++)
{
fprintf(file, "%c %c %c", ARP_table[i].IPaddr, ARP_table[i].MACaddr, ARP_table[i].ARPstatus);
}
}
You are not checking the return value of fopen. I am pretty sure you are not allowed to write to that file.
FILE *file = fopen(filename, "a");
if (NULL == file) {
perror("fopen");
/* return / exit */
}
Here is /proc/net/arp on my system
[cnicutar#aiur ~]$ ls -l /proc/net/arp
-r--r--r-- 1 root root 0 Jun 8 16:29 /proc/net/arp
Well for one thing, i<i+j will always be true, as long as j (which you haven't shown) is positive.
Then you're trying to display strings with %c, which should be %s.
As for the segmentation fault, your ARP_table is most likely 0 or garbage, but since you don't actually show how it's created, best of luck with that.
As an aside, I feel I need to point out that that's some horrible looking code. Basic questions like "what are those variables?" should never be asked if you have the full function code and type definition. Instead of being globals they should be passed as parameters from functions better equipped to handle them.
You can't write to /proc/net/arp , it's for reading only. (and changing the arp table otherwise is non trivial, you're better off running the external ip or arp command with proper arguments.
Check the return value of fopen, it might fail.
Where's ARP_table and j defined ? Perhaps there's something wrong there.
The condition i > i+j looks weird, are you sure this is the proper condition, and that you shouldn't just stop when i < j ?
Does ARP_table[i].IPaddr contain something sensible ?
"%c %c %c" would be wrong. %c prints a single character. It sounds like the two first should be strings, so use "%s %s %c"
Where is j?
If j is a strict positive constant, you will run into an infinite loop,
because i is always smaller then i + [someting positive]. This will probably cause the error, because your array has only an finite number of elements.
If j is variable and gets negative, you will not run into an infinite loop, but you will produce an i bigger then the number of elements in your array ARP_table.

Resources