Loop counter missing odd numbers with fread in c - c

hi guys i have this function to tell me how many records are in a data file.
however whenever i run it it only reads the even records
ex: if i have 0 records it outputs 0
with 1 record it outputs 0
with 2 records it ouputs 1
with 3 it outputs 1
with 4 it outputs 2
(btw its for a customer and products database project
customer is a struct and filep is the pointer to the file customerfile which is defines above this code)
im running on eclipse and can only use the gnu89/90 dialect if that makes a diff
int CusFileNumber(void)
{
customer tempcus;
filep = fopen(customersFile, "r");
fseek (filep,0,SEEK_SET);
int counter =0;
while(!feof(filep))
{
fread(&tempcus,sizeof(customer),1,filep);
printf ("%d",counter);
counter ++;
}
fclose(filep);
return (counter-1);
}
so i updated the code to get rid of the feof
it looks like this
int CusFileNumber(void)
{
customer tempcus;
filep = fopen(customersFile, "r");
fseek (filep,0,SEEK_SET);
int counter =0;
while(fread(&tempcus, sizeof(customer), 1, filep) == 1)
{
printf ("%d",counter);
counter ++;
}
fclose(filep);
return (counter);
}
but im still getting the same problem this time it isnt counting the even numbers
meaning that on every odd number counter increments by 1 but stayed the same when i have an even number of records in the file
(its a .dat file btw)

You can't use feof(3) like that. It only tells you if the stream has already ended, not that it's about to. You need to put the fread call into your loop condition and check its return value:
while (fread(&tempcus, sizeof(customer), 1, filep) == 1)
Get rid of the feof call entirely.
Are you sure sizeof(customer) matches what's really in the file?
Why are you printing counter before you increment it?
Why are you returning counter - 1 instead of counter?

Related

C Program to count keywords from a keyword text file in a fake resume and display the result

#EDIT: I think the problem is that I put my 2 text files on desktop. Then, I move them to the same place as the source file and it works. But the program cannot run this time, the line:
cok = 0;
shows "exception thrown".
// end EDIT
I have the assignment at school to write a C program to create 2 text files. 1 file stores 25 keywords, and 1 file stores the fake resume. The problem is, my program cannot read my keywords.txt file. Anyone can help me? Thank you so much.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//*****************************************************
// MAIN FUNCTION
int main()
{
//File pointer for resume.txt file declared
FILE *fpR;
//File pointer for keywords.txt file declared and open it in read mode
FILE* fpK = fopen("keywords.txt", "r");
//To store character extracted from keyword.txt file
char cK;
//To store character extracted from resume.txt file
char cR;
//To store word extracted from keyword.txt file
char wordK[50];
//To store word extracted from resume.txt file
char wordR[50];
//To store the keywords
char keywords[10][50];
//To store the keywords counter and initializes it to zero
int keywordsCount[10] = { 0, 0, 0, 0 };
int coK, coR, r, r1;
coK = coR = r = r1 = 0;
//Checks if file is unable to open then display error message
if (fpK == NULL)
{
printf("Could not open files");
exit(0);
}//End of if
//Extracts a character from keyword.txt file and stores it in cK variable and Loops till end of file
while ((cK = fgetc(fpK)) != EOF)
{
//Checks if the character is comma
if (cK != ',')
{
//Store the character in wordK coK index position
wordK[coK] = cK;
//Increase the counter coK by one
coK++;
}//End of if
//If it is comma
else
{
//Stores null character
wordK[coK] = '\0';
//Copies the wordK to the keywords r index position and increase the counter r by one
strcpy(keywords[r++], wordK);
//Re initializes the counter to zero for next word
coK = 0;
fpR = fopen("resume.txt", "r");
//Extracts a character from resume.txt file and stores it in cR variable and Loops till end of file
while ((cR = fgetc(fpR)) != EOF)
{
//Checks if the character is space
if (cR != ' ')
{
//Store the character in wordR coR index position
wordR[coR] = cR;
//Increase the counter coR by one
coR++;
}//End of if
else
{
//Stores null character
wordR[coR] = '\0';
//Re initializes the counter to zero for next word
coR = 0;
//Compares word generated from keyword.txt file and word generated from resume.txt file
if (strcmp(wordK, wordR) == 0)
{
//If both the words are same then increase the keywordCounter arrays r1 index position value by one
keywordsCount[r1] += 1;
}//End of if
}//End of else
}//End of inner while loop
//Increase the counter by one
r1++;
//Close the file for resume
fclose(fpR);
}//End of else
}//End of outer while loop
//Close the file for keyword
fclose(fpK);
//Display the result
printf("\n Result \n");
for (r = 0; r < r1; r++)
printf("\n Keyword: %s %d time available", keywords[r], keywordsCount[r]);
}//End of main
I think the problem is the text files, aren't they?
The name of my 1st test file is "keywords.txt", and its content is:
Java, CSS, HTML, XHTML, MySQL, College, University, Design, Development, Security, Skills, Tools, C, Programming, Linux, Scripting, Network, Windows, NT
The name of my 2nd test file is "resume.txt", and its content is:
Junior Web developer able to build a Web presence from the ground up -- from concept, navigation, layout, and programming to UX and SEO. Skilled at writing well-designed, testable, and efficient code using current best practices in Web development. Fast learner, hard worker, and team player who is proficient in an array of scripting languages and multimedia Web tools. (Something like this).
I don't see any problem with these 2 files. But my program still cannot open the file and the output keeps showing "Could not open files".
while ((cK = fgetc(fpK)) != EOF)
If you check the documentation, you can see that fgets returns an int. But since cK is a char, you force a conversion to char, which can change its value. You then compare the possibly changed value to EOF, which is not correct. You need to compare the value that fgets returns to EOF since fgetc returns an EOF on end of file.

Reading, translating and writing data between multiple CSV files using C

I have 3 CSV files. The first of them contains 4 columns:
ID,Section1,Section2,Secion3
1,23,12,7
2,11,26,9
. . . .
. . . .
19,30,22,4
20,5,6,16
The first column is the ID and the other three contain random numbers ranging from 0 to 30.
The next file is a "conversion" file. It shows the corresponding value to each number:
30,45,44,45
29,44,42,43
28,43,42,41
. . . .
. . . .
1,22,21,22
0,20,21,21
The first column is the number to be read and the next columns are the values that will replace those numbers in each Section.
Like, if you read a 30 in Section1 it will be replaced by a 45, and if you find a 29 in Section 2 it will be replaced by a 42 and so on.
If I were to write the converted numbers into a third CSV file with the same 4 column format, how should I do it?
So far I've had no problems with generating the files since they are randomized, except for the "conversion" file, but I don't know how to proceed with the conversion.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main (int argc,char *argv[]){
int i, num1;
char numbers[20][20];
char conversions[20][20];
//File with the initial numbers
FILE *registry = fopen("registry.csv","w+");
if (registry == NULL){
fputs ("File error",stderr);
exit (1);
}
//Conversion file
FILE *conversion = fopen("conversion.csv","r");
if (conversion == NULL){
fputs ("File error",stderr);
exit (1);
}
//File where the resulting values will be written
FILE *results = fopen("results.csv","a");
if (results == NULL){
fputs ("File error",stderr);
exit (1);
}
//Writing the headers
fprintf(results,"ID,Results1,Results2,Results3\n");
fprintf(registry,"ID,Section1,Section2,Section3\n");
srand(time(0));
//Generating the random numbers
for(i=1;i<21;i++){
sprintf(numbers[i],"%d,%d,%d,%d\n",i,rand()%31,rand()%31,
rand()%31);
fputs(numbers[i], registry);
}
//This is where I don't know how to proceed
for(i=1;i<21;i++){
sprintf(conversions[i],"%d,%d,%d,%d\n",i,
fscanf(registry,"%d,%*s,%*s,%*s\n",num1)...);
}
I was trying to do something like what I did to generate the random numbers by saving everything into a buffer and then writing it into the file and I found that the fscanf function can be of great use to skip the parts I don't need to read, but I couldn't figure out how to use it to skip the headers and the ID column and I'm still missing the conversion part.
Conversion file:
30,45,44,45
29,44,43,43
28,43,42,42
27,43,41,40
26,41,40,40
25,40,39,39
24,39,37,39
23,38,37,38
22,38,36,37
21,36,36,37
20,35,35,36
19,34,34,35
18,33,34,35
17,33,33,34
16,32,32,33
15,32,31,32
14,31,30,31
13,30,30,31
12,29,29,30
11,29,28,29
10,28,28,29
9,28,27,27
8,27,26,26
7,27,26,25
6,26,25,25
5,25,24,24
4,25,23,24
3,24,23,23
2,23,22,21
1,21,21,20
0,20,21,20
This answer is scoped to address:
//This is where I don't know how to proceed.
To do what you have described, if it is not necessary to include the first columns in registry, results or conversion for storing, then do not. Although nice for human readability, they complicate the task of reading in, and using arrays. The unused column data and header row requires array indexing gymnastics to get the data to line up correctly into the arrays.
Without the header row and numbering column, array indexes alone are sufficient to track all that is needed to make the conversion.
However, if you feel the first column/row is needed for your purposes, then adjust the array indexing of the routines shown below to accommodate.
The following steps (some of which you already do) are what I identified as essential toward making the conversion step as simple as possible...
Steps:
Create registry - 60 - random numbers (0-30) arranged in 20 rows, 3
data columns
Create int reg[20][3] = {{0}};
Read registry into reg array using a combination fgets sscanf routine.
Example:(assuming registry has already been created in your code)
registry = fopen(".\\registry.csv","r");
if (registry)
{
while(fgets(buf, sizeof(buf), registry))
{
sscanf(buf, "%d,%d,%d", &reg[index][0],&reg[index][1],&reg[index][2] );
index++;
}
fclose(registry);
}
conversion table - pre-existing file
Create int conv[31][3] = {{0}};
Read conversion table into conv array using a combination fgets sscanf routine (see above example)
Once you have these arrays created properly,
Perform conversion:
Create int res[20][3] = {{0}};
Create char buf[80] = {0};
Open 'results' file: FILE *results = fopen(".\\results.csv","w");
populate results:
Example:
//File where the resulting values will be written
FILE *results = fopen(".\\results.csv","w");
if (results)
{
for(i=0;i<sizeof(reg)/sizeof(reg[0]);i++)
{
for(j=0;j<sizeof(reg[0])/sizeof(reg[0][0]);j++)
{
res[i][j] = conv[reg[i][j]][j];
// | | |___reg col == conv col
// | |______value reg == conv row
// |________________________________row and column of conv
}
sprintf(buf, "%d,%d,%d\n", res[i][0],res[i][1],res[i][2]);
fputs(buf, results);
}
fclose(results);
}
At this point, you can print the results file in a format that suits your needs.
Following is an image showing actual results using suggested approaches above for a randomly generated registry, the values you provided for conversion and resulting results. (each created without column 1 shown in your original code, as I suggested in my comments.) Image is showing indexing from 0 - n for each set of array data:

How do I read a text file and store it in an array in C programming (values seperated by a comma)?

I need help with getting datapoints, x and y values from a txt file into two arrays.
Currently, the text file consists of 5 lines like:
0.116
0.118
0.12
0.122
0.124
This is my code:
#include <stdio.h>
#include <stdlib.h>
main(void)
{
FILE *inp; /* pointer to input file */
double item;
int cnt=0,y,d,i;
double array[300],swap;
/* Prepare files for input */
inp = fopen("testdoc.txt", "r");
/* Read each item */
while ( (fscanf(inp, "%lf", &item) == 1) && (!feof(inp)) ) {
array[cnt] = item;
cnt++;
}
for (int i = 0; i < cnt; i++)
{
printf("%lf\n",array[i]);
}
printf("The total number of inputs is %d",cnt);
fclose(inp); /* Close the files */
return (0);
}
This only reads the first half of the file, which are the x values. Of which output is
0.116000
0.118000
0.120000
0.122000
The total number of inputs is 4
However, I want to read a text file and store the values in two different arrays for x and y values.
The new text file will look like this
0.116,-0.84009
0.118,4.862
0.12,-1.0977
0.122,0.22946
0.124,3.3173
How do i go changing my code above to recognize the Y values after "," sign? And to add both into two arrays at once?
I tried compiling your code posted on pastebin and received an error because of a missing bracket in your while statement.
That's an easy fix.
The larger issue is in the condition of the while loop.
fscanf returns the number of input items converted and assigned on each call.
When you modified your code to return two values, the condition in the while loop fscanf(inp, "%lf,%lf", &v1,&v2) == 1 would fail and the loop will not be entered.
Please modify the while statement to (have included the missing "(" too)..
while ( (fscanf(inp, "%lf, %lf", &v1, &v2) == 2) && (!feof(inp)) )
and you should be good to go!!!
In addition it would be a good practice to include the return type of int for the main function.

Creating and writing in multiple txt files in C

I've got a code which creates j files (Node[j].ID) in a directory called (Nodes) and in those j files the code writes the info contained in NodeResults. At the moment the code doesn't neither create nor write in files because of the strcat function doesn't work. Please any idea how to correct the code in order to get the created files with the info contained in NodeResults on it?. Thanks in advance. Please find the code below:
{
int period, j ;
FILE*temporal;
FILE* temp_time;
char path[25];
char* extention = ".txt";
char s[30];
char temporal2[25];
long time_val = 0;
_mkdir("Nodes");
_mkdir("time");
temp_time = fopen("Time/time.txt", "w");
fprintf(temp_time, "%d,%d\n", ReportStep, Nperiods);
fclose(temp_time);
for ( j = 0; j < Nobjects[NODE]; j++ ) {
/* File path writing */
strcpy(temporal2,"Nodes/");
strcat(temporal2, Node[j].ID);
strcat(temporal2, extention);
temporal= fopen(temporal2, "w");
}
for ( period = 1; period <= Nperiods; period++ ) {
output_readNodeResults(period, j);
fprintf(temporal, "%9.3f,%9.3f,%9.3f,%9.3f,%9.3f\n",
NodeResults[NODE_INFLOW],
NodeResults[NODE_OVERFLOW],
NodeResults[NODE_DEPTH],
//NodeResults[NODE_HEAD],
NodeResults[NODE_VOLUME]);
}
fclose(temporal);
return Nperiods;
}
You open a bunch of files in the first for loop, but do not write anything to them. At each iteration, you assign a new FILE * to variable temporal, overwriting any previous value. Afterward, in your second for loop you write a bunch of output to the last file opened -- the one to which temporal refers at that point.
It looks like you want to move the body of the second for loop and the fclose() into the first for loop.
I have properly formatted your code, and now John's comment immediately sticks out: the brace is on the wrong line, resulting in wrong for loops and blocks!
Should you have formatted the code properly yourself, you would have seen it immediately yourself!

Where am I going wrong in getting this function to do what I would like?

I have written the following function in my C program. The program loads a text file (Les Miserables Vol. I) as well as another text file of 20 of the characters names. The purpose of this function is to scan the entire file, line by line, and count the number of times any of the 20 names appear.
NumOfNames = 20.
Names is an array of the 20 names stored from Names[1] - Names[20].
MaxName is a global integer variable which I would like to store the total number of name appearances throughout the file (It should be in the hundreds or even thousands).
EDIT: After the function is executed, the value of MaxName is 4. I am completely lost as to where I have made a mistake, but it appears that I have made several mistakes throughout the function. One seems to be that it only executed the first iteration of the for loop i.e. it only searches for Name[1], however the first name appears 196 times in the file, so it still isnt even working correctly for just the first name.
void MaxNameAppearances()
{
char LineOfText[85];
char *TempName;
FILE *fpn = fopen(LesMisFilePath, "r+");
for(i = 1; i<=NumOfNames; i++)
{
while(fgets(LineOfText, sizeof(LineOfText), fpn))
{
TempName = strstr(LineOfText, Names[i]);
if(TempName != NULL)
{
MaxName++;
}
}
}
fclose(fpn);
}
I guess that one problem of the code is that it would have to read the file upon every iteration of i. Try to re-order the loops like this:
while(fgets(LineOfText, sizeof(LineOfText), fpn))
{
for(i = 1; i<=NumOfNames; i++)
{
TempName = strstr(LineOfText, Names[i]);
if(TempName != NULL)
{
MaxName++;
}
}
}
This reads a line, checks the occurrances of all names in that line and then goes on to the next line.
If you do it your way, you will be at the end of file for i == 1 already.

Resources