C Writing into file stop working after use it as function? - c

I wrote a function that sets every number of a line in a .txt file to zero and clears the other file.
I originally wrote this logic in main and it worked perfectly fine. But now I need to make a menu for my program, so I need to put this logic into a function.
That's where the things go wrong. Once I move the logic into a function, it doesn't set the numbers to zero, it just clears the file, and I didn't changed anything.
Expected result:
Workers.txt : Adam Washington Monday Friday --(use function)--> {clear}
days.txt: 1 0 0 0 1 0 0 --(use function)--> 0 0 0 0 0 0 0
Actual result:
It's clear in both files.
void ResetOwnData(){
printf("--------------------------------------------------------------------------\n");
FILE* freset = fopen ("workers.txt", "w");
close(freset);
FILE* freset2 = fopen ("days.txt", "w");
for(int i = 0; i < 7; i++){
fprintf(freset2,"%d ",i+1);
}
fprintf(freset2,"\n");
for(int i = 0; i < 7; i++){
fprintf(freset2,"%d ",0);
}
close(freset2);
printf("Everything get reset!\n");
printf("--------------------------------------------------------------------------\n");
}

There are two main things that appear to be incorrect.
You are using close rather than fclose. fclose is used with file streams (like you are using)
Your function is overwriting the one line that you want (e.g., 0 0 0 0 0 0 0) with two lines because you have two for loops
Here is a CodingGround link to the corrections that I believe you are seeking.
You should add some error checking to ensure that you truly have opened the file and that you release any allocated memory

Related

Issues Reading a CSV file into a C Struct

I've just started learning C, and I'm currently trying to create a program to automate a fishing minigame I made for my D&D campaign. In order to do so, I created a CSV containing all the tables I had originally written up. I've been trying a variety of things for about a week now to just simply read the CSV into C so that I can call specific elements at will. I've finally gotten something to very nearly work, but I'm getting a strange problem. Firstly, the CSV is formatted as such:
bluefish,str,2,5
bluefish,str,2,5
bluefish,str,2,5
bluefish,str,2,5
kahawai,dex,2,1000
narrow barred mackerel,str,3,5
It goes on for another 400 lines, but you get the point. My current code looks like the following:
typedef struct{
char name[50];
char contest[5];
int modifier;
int value;
} fts_t;
/*Checking for the file and opening it*/
FILE *tpointer;
tpointer = fopen("fishing_tables.csv", "r");
printf("Accessing Fishing Tables...\n");
if(tpointer == NULL){
printf("Error: Missing fishing_tables.csv");
return 0;
} else{
printf("Success! Importing Data...\n");
}
/*Creating a struct array and initializing variables*/
fts_t ft[400];
char buffer[1024];
int count = 0;
char name[100];
char contest[3];
int modifier;
int value;
while(fgets(buffer, 1024, tpointer)){
sscanf(buffer, " %[^,],%[^,],%d,%d", name, contest, &modifier, &value);
strcpy(ft[count].name, name);
strcpy(ft[count].contest, contest);
ft[count].modifier = modifier;
ft[count].value = value;
printf("%s\t%s\t%d\t%d\n", ft[count].name, ft[count].contest, ft[count].modifier, ft[count].value);
count++;
}
So, following above, I'm having it print out the elements of the struct at each count as it loops, just to check that it's creating the struct correctly. The problem comes in that the output looks like this:
dex 2 15
dex 2 15
dex 2 15
dex 2 15
dex 2 15
next 0 0 0
next 0 0 0
next 0 0 0
next 0 0 0
next 0 0 0
Now, hilariously, the rows beginning with "next" are the only rows printing correctly. I have these added in for some extra shenanigans in the context of the minigame, but what's important is that those are correct. However, in every other row, the name variable is not being read, and I'm really lost as to why, when the "next" rows are functioning fine. I've checked the actual variable itself, and it appears there's some sort of problem in my sscanf statement.
Any help is appreciated.

How does fread() in C work inside a for loop?

I am new to C programming, but I need it to read some binary file which I describe below.
The India Meteorological Department (IMD) has provided historical weather data in .GRD files in their website. They have also provided sample C code to read those files. From their sample C code, I have written the following code that extracts the daily minimum temperatures on 15 April 1980 recorded on a 31x31 grid over India.
/* This program reads binary data for 365/366 days and writes in ascii file. */
#include <stdio.h>
int main() {
float t[31][31];
int i,j ,k;
FILE *fin,*fout;
fin = fopen("C:\\New folder\\Mintemp_MinT_1980.GRD","rb"); // Input file
fout = fopen("C:\\New folder\\MINT15APR1980.TXT","w"); // Output file
fprintf(fout,"Daily Minimum Tempereture for 15 April 1980\n");
if(fin == NULL) {
printf("Can't open file");
return 0;
}
if(fout == NULL) {
printf("Can't open file");
return 0;
}
for(k=0 ; k<366 ; k++) {
fread(&t,sizeof(t),1,fin);
if(k == 105) {
for(i=0 ; i < 31 ; i++) {
fprintf(fout,"\n") ;
for(j=0 ; j < 31 ; j++)
fprintf(fout,"%6.2f",t[i][j]);
}
}
}
fclose(fin);
fclose(fout);
return 0;
}
/* end of main */
The file Mintemp_MinT_1980.GRD can be downloaded from the IMD website by selecting the year as 1980 against Minimum Temperature.
What I don't understand is that how the fread() function actually works in the line fread(&t,sizeof(t),1,fin) within the loop for(k=0 ; k<366 ; k++). In plain sight, the arguments of fread() here do not depend on the looping variable k, and so it should read the same data to the matrix t[31][31] for every k. However, I have checked that, surprisingly, the data extracted by this program are different for different values of k in the line if(k == 105), i.e., the data extracted for k == 105 and k == 32 are different, for example.
I would very much appreciate if one can please explain the above.
Files contain sequential data. All the file operators are based on the premise that whatever you do to a file, you'll generally be doing it in a sequential way.
So when you read data, and then read more data, you will be getting sequential chunks of the file. The both the FILE datatype and the operating system itself do a number of things for you, including keeping track of your current position in the file and doing block buffering in memory to improve performance.
If you wanted to reread the same data over, or skip around in the file, you would need to use fseek() to change positions in the file before doing your next read.

How to read one line at a time from a data file and to perform calculations in it before moving to the next line in C Programming?

I'm a beginner at C programming and I would appreciate some help in order to understand the problem.
Alright so, I have a data file (input.dat) with data like this: (first line) 0 2 3 4 5; (second line) 1 2 3 5 4, (third line and so on...). I'm required to read the data one line at a time until the end of file and print it. This is what I have done so far:
int main(void)
{
float coeffs[5];
FILE *input; /* File pointer to the input file */
fopen_s(&input, "input.dat", "r"); /* Location of the input file */
int count = 0;
/* Loops to read data set*/
while (fscanf_s(input, "%f %f %f %f %f ", &coeffs[0], &coeffs[1], &coeffs[2], &coeffs[3], &coeffs[4]) != EOF)
{
printf("a=%.4f; b=%.4f; c=%.4f; d=%.4f; e=%.4f\n", coeffs[0], coeffs[1], coeffs[2], coeffs[3], coeffs[4]);
count++;
}
return 0;
}
This is showing all of the lines in the data file at once. But this is not what I want. I need to read one line at a time and perform some calculations and conditions for that one line first before I move to the next line. So how can I do that?
Next problem is, for the first line, I need to implement a loop from -10 to +10 with increment of 2 (to get 11 results in total). For example the program will read the first line, display it on the screen, then for the first value -10, the program will calculate and again display something . Then it will do the same for -8, then for -6 and so on until +10. After the 11 results are displayed, the program will then and ONLY then, move to the second line and so on. Hence for each line in the data file, the program will have 11 results. How can I use the loop function with increment of 2 to achieve these 11 results?
I would appreciate if anyone can provide me a simple layout of the structure of the codes which I've to write. NOTE: The formats are a bit different than other compilers as I must use Microsoft Visual Studio to do it.
Add your calculations to your while loop. You are reading one line at a time anyway.
If you want to loop from -10 to 10 with increments of 2, use a for loop.
for(count = -10; count <= 10; count = count + 2)
{
// Calculations
}

C reading file using ./a.out<filename and how to stop reading

In my class today we were assigned a project that involves reading in a file using the ./a.out"<"filename command. The contents of the file look like this
16915 46.25 32 32
10492 34.05 56 52
10027 98.53 94 44
13926 32.94 19 65
15736 87.67 5 1
16429 31.00 58 25
15123 49.93 65 38
19802 37.89 10 20
-1
but larger
My issue is that any scanf used afterwards is completely ignored and just scans in what looks like garbage when printed out, rather than taking in user input. In my actual program this is causing an issue with a menu that requires input.
How do I get the program to stop reading the file provided by the ./a.out"<"filename command?
also I stop searching at -1 rather than EOF for the sake of not having an extra set of array data starting with -1
ex
-1 0 0 0
in my real program the class size is a constant that is adjustable and is used to calculate class averages, I'd rather not have a set of 0's skewing that data.
#include <stdio.h>
int main(void)
{
int i = 0,j = 1,d,euid[200],num;
int tester = 0;
float hw[200],ex1[200],ex2[200];
while(j)
{
scanf("%d",&tester);
if( tester == -1)
{
j = 0;
}
else
{
euid[i] = tester;
}
scanf("%f",hw+i);
scanf("%f",ex1+i);
scanf("%f",ex2+i);
i++;
}
for(d = 0;d < 50;d++) /*50 because the actual file size contains much more than example*/
{
printf("euid = %d\n",euid[d]);
printf("hw = %f\n",hw[d]);
printf("ex1 = %f\n",ex1[d]);
printf("ex2 = %f\n",ex2[d]);
}
printf("input something user\n");
scanf("%d",&num);
printf("This is what is being printed out -> %d\n",num);
return 0;
}
I'm having the exact same problem. Tried every method I could find to eat the remaining input in the buffer, but it never ends.
Got it to work using fopen and fscanf, but the prof. said he prefers the code using a.out < filename
Turns out this is in fact not possible.

check for zero bytes

I have made a piece of code that checks for zeroes in blocks of 512 bytes. A problem I have is that it doesn't seem to check all bytes if I build a check in, here is the code:
int zerocheck(FILE *fp,unsigned long long seekpoint)
{
int j;
if(fseek(fp,seekpoint,SEEK_SET)==0)
{
char buf[seekwidth],cmp[seekwidth];
if(fread(buf,sizeof buf,1,fp)==1)
{
for (j=0;j<seekwidth;j++)
{
printf("%i\n!!!\n",buf[j]);
if (buf[j]!=0)
return 1;
else
return 0;
}
}
}
return 2;
}
the print is just there for debugging. the problem is it doesn't seem to check all bytes properly if the check for a zero is there. I can see from the print that it prints out a 1 if I have a 1! but as soon as I add the if statement after it doesn't print out the 1 and doesn't return the proper value. I have no idea how to fix it...
for the record this what is happening I have a file which I KNOW the 2nd byte is a 1. if I remove:
if (buf[j]!=0)
return 1;
else
return 0;
it reads correctly and gives out this:
checking file for zeroes...
0
!!!
1
!!!
0
but if the if statement is included this is the output:
checking file for zeroes...
0
!!!
0
!!!
0
the printing is not really the issue but it is important the every byte get checked...
You only check the first byte, then return one or zero immediately! If it is zero, as expected, you need to carry on to the next byte.
Try removing the two lines that say:
else
return 0;
Then replace the final:
return 2;
with
return 0;
then your function will return zero if the entire block is zero and one if the block is non-zero.

Resources