Characters missing when writing in file in C - c

I've searched all I could and I'm actually not sure how to look for an answer as it's pretty specific.
I have a function that checks if a file exists and if it doesn't, create it and writes some parameters in it. After that another function adds some data in the file. But the first line of data is missing the number of characters that are in the line created with the file.
The code looks like this (I'm only putting the parts I think are relevant, as it's pretty messy) :
the function that checks if the file exists is :
int check_datafile(char *fname, Par *par){
char filename[64] = "data/";
strcat(filename, fname);
FILE* fdesc = NULL;
fdesc = fopen(filename, "r");
if (fdesc == NULL){
fdesc = fopen(filename, "w");
fprintf(fdesc,"%d %.3f \n", par -> L, par -> t);
close(fdesc);
}
return 1;
}
Then the function that writes is :
void result_block(Par *par, double M, double M2, double M4, int ntot, char *fname)
{
char filename[64] = "data/";
strcat(filename, fname);
FILE* fichier = NULL;
fichier = fopen(filename, "a");
if (fichier != NULL) // File should already exist
{
fprintf(fichier, "%.3f %.3f %.3f\n", M/ntot, M2/ntot, M4/ntot);
fclose(fichier);
}
else
{
printf("Problem with the file : %s\n", filename);
exit(0);
}
}
They are called by
int initialize_mc(Par *par, int *spin) {
int i, L2 = par->L * par->L;
double T = par -> t;
char *f2;
double ex[1];
ex[0] = exp(-2/T);
if (!par->L) {
printf("Give system size N!\n");
return 0;
}
init_ran(par->seed);
sprintf(fname, "%3.3d_%5.3f", par->L, par->t);
check_datafile(fname, par);
mc(par, spin, ex);
return 1;
}
And the function result_block is called in the function mc.
Typically, I want the file to look like this :
16 2.210
205.412 43371.160 2010463301.344
201.876 42319.600 1951381846.720
198.396 40897.632 1836904396.032
197.652 40743.856 1833699088.000
...
And it looks like this :
16 2.210
371.160 2010463301.344
201.876 42319.600 1951381846.720
198.396 40897.632 1836904396.032
197.652 40743.856 1833699088.000
...
The the first line of data is cut by the same amount of characters that is in the first line of the file.
What can cause this problem?

close(fdesc); needs to be fclose(fdesc);. When you use FILE * you are implicitly using a buffer on your output. You need to call fclose so that the buffer gets flushed.
By calling close you are actually casting your pointer to an int and closing some random file descriptor (which presumably fails most of the time). You're not closing the FILE * at all.

Related

Am I using typedef structures and arrays correctly to read my file? It is not opening

I'm a beginner in data structures with C, I have taken C programming but I've only touched a little bit on structures in the course and I have not kept up with it.
Anyways, I'm trying to make a program that will read data into an array of structures from a file and print out the contents of the array you have populated. I need help figuring this out.. I'm honestly not too sure if I'm doing this correctly either... :/
Any help is greatly appreciated, and thank you in advance! :)
This is what I tried so far
Here's my code:
FYI - The file I'm trying to open is DataFile.txt
#include<stdio.h>
#include <stdlib.h>
#define SIZE 10
#define ARRAY_SIZE 30
//Struct contains 3 fields, name, age, salary
typedef struct
{
char name[SIZE];
int age;
int salary;
} data;
data a[ARRAY_SIZE];
FILE * fp = fopen("DataFile.txt", "r");
if (fp == NULL)
{
printf("Error %s.\n", strerror(errno));
exit(1);
}
int GetData()
{
int i = 0;
fscanf(fp, "%s", a[i].name);
while(fp && i<ARRAY_SIZE)
{
fscanf(fp, "%d", &a[i].age);
fscanf(fp, "%d", &a[i].salary);
i++;
}
return i;
}
void ShowData( int records_read)
{
//Print text file data on screen
for(int i=0;i<records_read;i++)
{
printf("%s %d %d\n", a[i].name, a[i].age, a[i].salary);
}
}
int main()
{
char name[256];
int i = 0;
int records_read;
//Call the method, getData
i = GetData();
//Prompt and read input from the user
printf("Pick a number from 1 to 10:");
scanf("%d", &records_read);
//Call the method, showData
ShowData(records_read);
fclose(fp);
return 0;
}
The program works if I don't put this part of the code in:
FILE * fp = fopen("DataFile.txt", "r");
if (fp == NULL)
{
printf("Error %s.\n", strerror(errno));
exit(1);
}
BUT the output is just a list of zeros..
A quick answer: At first, try to split FILE * fp = fopen("DataFile.txt", "r"); into two parts as one is the variable declaration FILE * fp = NULL; and the other one is the assignment expression fp = fopen("DataFile.txt", "r");. And then keeps the part of the variable declaration out of all the functions, while moves both the part of the assignment and the if-statement if (fp == NULL){...} into function GetData(). The code might work in this case.

How to dump txt file in C?

#include <stdio.h>
int main(void) {
int name;
int arrival_time;
int size;
int ret;
FILE * fp = fopen_s("C:\\NIA\\data.txt", "rt");
while (1)
{
ret = fscanf_s(fp, "%d %d %d", &name, &arrival_time, &size);
if (ret == EOF)
break;
printf("%d %d %d \n", name, arrival_time, size);
}
return 0;
}
I want to dump my txt file to project but errors are coming out. I'm confused about memory initiation and file format, variables, etc. How can I fix this and print values well?
My txt file is :
Your question lacks the most important information: What is going wrong.
When I compile your code, I get errors for fopen_s. (OK, this is mainly because I use gcc ;) )
The manual tells us how this function looks like:
errno_t fopen_s(
FILE** pFile,
const char *filename,
const char *mode
);
This means, you must use it like this:
errno_t err;
FILE *fp;
err = fopen_s(&fp, "C:\\NIA\\data.txt", "rt");
if (err != 0)
{
fprintf(stderr, "The file was not opened\n" );
exit(1);
}
Or you stick to standard functions and use them as you already tried:
FILE *fp;
fp = fopen("C:\\NIA\\data.txt", "rt");
if (fp = NULL)
{
fprintf(stderr, "The file was not opened\n" );
exit(1);
}
You should definitely add checks for all return values. At least for I/O related functions like fopen and scanf.
Also closing your file would be adviseable. While it is only opened in read mode, it will not cause much trouble as it is closed automatically on program termination, but it is surely good style to do it.
An improved version could look like this:
(As you do not scan strings, there is no benefit using MS non-standard function scanf_s)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int name;
int arrival_time;
int size;
FILE * fp = fopen("data.txt", "rt");
if (fp == NULL) {
perror("File data.txt cannot be opened");
exit(1);
}
while (fscanf(fp, "%d %d %d", &name, &arrival_time, &size) == 3)
{
printf("%d %d %d\n", name, arrival_time, size);
}
fclose(fp);
return 0;
}
This prints the content of your data.txt file on the console.
If dumping you txt file means closing the txt file after using it, you can use the following
fclose(fp);
before the return 0;

Why am I getting "Segmentation Fault" when I run my program?

My program decodes an image that is covered by random pixels, to decode the image, I have to multiply each pixel's red color component by 10. The green and blue color components are the same values as the new red component. I've created multiple helper functions, to make the code easier to read in main, but when I try to run my a.out, I keep getting "Segmentation Fault". I can't seem to find my mistakes! Help is appreciated.
void check_argument(int arg_list)
{
if (arg_list < 2)
{
perror("usage: a.out <input file>\n");
}
}
void print_pixel(int a, FILE *out)
{
int r, g, b;
r = a * 10;
if (r > 255)
{
r = 255;
}
g = r;
b = r;
fprintf(out, "%d\n", r);
fprintf(out, "%d\n", g);
fprintf(out, "%d\n", b);
}
void read_header(FILE *in)
{
char str[20];
for (int i = 0; i < 3; i++)
{
fgets(str, 20, in);
}
}
FILE* open_files(FILE *infile, char *input[])
{
infile = fopen(input[1], "r");
if (infile == NULL)
{
perror("Error: Cannot read file.\n");
}
return infile;
}
void decode(int arg_list, char *in[])
{
FILE *input, *output;
int check, red, green, blue;
open_files(input, in);
output = fopen("hidden.ppm", "w");
fprintf(output, "P3\n");
fprintf(output, "%d %d\n", 500, 375);
fprintf(output, "255\n");
read_header(input);
check = fscanf(input, "%d %d %d", &red, &green, &blue);
while (check != EOF)
{
print_pixel(red, output);
check = fscanf(input, "%d %d %d", &red, &green, &blue);
}
fclose(input);
fclose(output);
}
int main(int argc, char *argv[])
{
check_argument(argc);
decode(argc, argv);
}
After calling open_files(input, in); you will not have the file handle in input.
As this is supposed to be homework, I'll try to show you the some common source of bugs and how to find them.
Variables which are used must (should) be assigned to before that. This counts especially for pointers, e. g. FILE *.
If a function (e. g. fopen()) fails, it normally indicates this by returning a special value which must be checked before continuing.
To check which value a variable has, you can use printf() to show it.
This is for finding principal errors such as segfaults.
But logical errors are hard to find as well: if you read 3 values and store them into variables, it might be more useful to use them all instead of only one of them. (But maybe this one is not yet the goal of this exercise.)
I wrote the lines before this before I learned that it is not the task to search for bugs in a given program, but to write a program by yourself, so I'll get a little more concrete by now.
A FILE * is something returned by fopen(). You can return it or you can write it to a variable or another memory location indirectly pointed to by a pointer "one level deeper".
So you should rewrite your open_files() (BTW: why file*s*? It's currently only one...):
either for returning the value (preferrable):
FILE* open_files(char *input[])
{
FILE *infile = fopen(input[1], "r");
if (infile == NULL)
{
perror("Error: Cannot read file.\n");
}
return infile;
}
and call it with
input = open_files(input);
or with "pass by reference":
void open_files(FILE **infile, char *input[])
{
*infile = fopen(input[1], "r");
if (*infile == NULL)
{
perror("Error: Cannot read file.\n");
}
return *infile;
}
and call it with
open_files(&input, in);
Only doing that you'll have your variable input at the caller's site really written to.

C - reading a file and appending data to another

I am trying to open a file (that wants to be a small archive) and I want to copy another file content in it. The code is the following:
FILE * arch;
FILE * par;
void read_words (FILE *f)
{
char x[1024];
while (fscanf(f," %s",x)==1)
{
fprintf(arch," %s", x);
}
}
int main(int argc, char * argv[])
{
char * nome;
nome = argv[1];
archivio = scrivi(getcwd(NULL, 0), nome);
arch = fopen(archivio, "w+");
par = fopen(argv[2], "r+");
read_words(par);
return 0;
}
Please assume that "archivio" is a working path.
i call the function as follows: ./a.out archiveName FilePath.
All i want to do is opening this archive, then, after some fprintfs (that work correctly, not shown here) opening another file and write its content in archive.
The problem is in the function read_words. It works if taken alone (I took code from here), but if I insert that here, it doesn't work, because it doesn't even enter in while (fscanf(f," %s",x)==1). In fact archive file is always empty.
Can you help me find out why?
Thanks
PS: This is an example text i tried to insert:
La funzione mkbkp si occupa della creazione di un archivio contenente i file e le cartelle passate come parametri.
The strange thing is that if you make a c file with only read_words, it works fine.
Given the way you describe the behavior of your program, I can only suppose that you are not reading the file that you want to be reading. Try using this function:
void show_file (const char *filename, FILE *out) {
int c;
FILE *file;
fprintf(out, "%s(%s) BEGIN\n", __func__, filename);
file = fopen(filename, "r");
if (file) {
while ((c = fgetc(file)) != EOF) {
fputc(c, out);
}
fclose(file);
} else {
fprintf(out, "%s: failed to open file '%s' (%d)\n", __func__, filename, errno);
}
fprintf(out, "%s(%s) END\n", __func__, filename);
}
You can call this function from your main like this:
show_file(argv[2], stderr);
Make sure the path to the file and the contents of the file match your expectations.

Using fscan() for a file, how can I do something with the values inside the file?

So if I have a file with several numbers, and I open the file using
fp = fopen (filename, "r");
So now I can read the contents of the file correct? How could I do something with the file. Like in this file there are numbers and I want to be able to add them up.
fscanf(fp)
would be the beginning of what is supposed to be correct? But I am not sure what to do beyond it. What code represents the items inside the file I am opening? If it is "x" then I want to add all the "x"'s up and then divide it by the total number of files there are.
How can I use the variables inside a file and do things with them?
Edited code:
if (fp != NULL)
{
while (fscanf(fp, "%lf", &d) == 1)
sum += d;
mean = sum / total;
printf ("The number of data values read from this file was %.0lf\n", total);
printf ("\n%.2lf\n", mean);
fclose(fp);
}
if (fp != NULL)
{
do
{
c = fgetc(fp);
if (c != EOF)
{
if ((char)c == '\n')
total++;
}
} while (feof(fp) == 0);
Simple example (not hardened) that adds the numbers read from a file...
#include <stdbool.h>
#include <stdio.h>
int main(int argc, char** argv)
{
float sum = 0;
float eachValue;
FILE *fp;
fp = fopen(argv[1], "r");
while (true)
{
int scanned = fscanf(fp, "%f\n", &eachValue);
if (scanned == 1)
{
sum += eachValue;
}
else
{
break;
}
}
fclose(fp);
printf("%f\n", sum);
}
For hardening, you should do things like deal with empty lines, validate there IS an arg[1] to be opened, deal with the cases where there's no file to be opened or some other error occurs during opening, etc.
If the only content in the file is valid numbers, this will work. Actually, it will work until the first text that isn't a valid number:
#include <stdio.h>
int main(void)
{
double sum = 0.0;
char const *filename = "data.file";
FILE *fp = fopen(filename, "r");
if (fp != 0)
{
double d;
while (fscanf(fp, "%lf", &d) == 1)
sum += d;
fclose(fp);
}
printf("%g\n", sum);
return(0);
}
As a general rule, if a function opens a file successfully, it should close it when it's finished. In this example, the system would close the file anyway, but it is as well to get into good habits. With a little more care and attention, you could distinguish between a format error (return value of 0 from fscanf()) and EOF or I/O error.
You can have these many functions to read from a file in general.
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int fscanf(FILE *restrict stream, const char *restrict format, ...);
size_t fread(void *restrict ptr, size_t size, size_t nitems,FILE *restrict stream);
depending upon your requirement use any one of this.
For example as you said , you have to add the numbers which are in the file.
So try reading from file with any of the above function into char array and then using delimiter (the character by which numbers are separated in file) parse the array into integer array or different numbers. Then it's easy to find the sum.
You should see man strtod
Also this man strtok

Resources