Problem with printf or scanf (wont print the number properly) - c

I am trying to read numbers from file, the function prints only the digits after the decimal point. any idea why this happens?
thanks!
float Read() {
int i, k, w, m, n, j;
float number;
float a[m];
FILE *fil1;
fil1 = fopen("numbers.txt", "r");
w = 0; k = 0;
while (fscanf(fil1, "%d", &n) != EOF) {
fscanf(fil1, "%f", &number);
a[k] = number;
printf("%d => %f \n", i, a[k]);
w++;k++;
}
}

You're scanning the file twice, you're basically skipping every second number. this should fix it.
float Read (){
int i,k,w,m,n,j;
float number;
float a[m];
FILE *fil1;
fil1 = fopen("numbers.txt","r");
w=0; k = 0;
while (fscanf(fil1, "%f", &n) != EOF){
a[k]=n;
printf ("%d => %f \n",i, a[k]);
w++;k++;}

change n to be float
and read it as float:
#include "stdio.h"
#pragma warning(disable : 4996)
float Read()
{
int k, w;
float n;
float a[100];
FILE* fil1;
fil1 = fopen("numbers.txt", "r");
w = 0; k = 0;
while (fscanf(fil1, "%f", &n) != EOF) {
a[k] = n;
printf("%f \n", a[k]);
w++; k++;
}
return 0;
}

Related

Why my code is printing last values retrieved from file instead of new one

I have the following code for reading files in C. It's reading from files but not like its supposed to be. It is showing up like this:
instead of like this:
Although I am calling the same print function. We are taking records for 4 employees. I know it's a logical error but I am unable to solve it.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct employee {
float hoursWorked, hourlyRate, federalTax, stateTax;
char name[20];
};
struct calc
{
float grosspay, fto, sto, np;
};
void print(struct employee s[], struct calc c[], int n)
{
for (int i = 0; i < 4; i++)
{
printf("\n%s's gross pay: $%.02f\n", s[i].name, c[i].grosspay);
printf("Federal tax owed: $%.02f\n", c[i].fto);
printf("State tax owed: $%.02f\n", c[i].sto);
printf("Net pay: $%.02f \n\n", c[i].np);
printf("\n");
}
}
void savetext(struct employee s[], struct calc c[], int n)
{
FILE *f;
f = fopen("employee.txt", "w");
for (int i = 0; i < n; i++)
{
fprintf(f, "%s\n", s[i].name);
fprintf(f, "%f %f %f %f\n", s[i].hoursWorked, s[i].hourlyRate, s[i].federalTax, s[i].stateTax);
fprintf(f, "%.2f %.2f %.2f %.2f\n", c[i].grosspay, c[i].fto, c[i].sto, c[i].np);
}
fclose(f);
}
void retrievetext(struct employee s[], struct calc c[], int n)
{
FILE *f;
int length;
f = fopen("employee.txt", "r");
for (int i = 0; i < n; i++)
{
fgets(s[i].name, sizeof(s[i].name), f);
length = (int)strlen(s[i].name);
s[i].name[length - 1] = '\0';
fscanf(f, "%f %f %f %f\n", &s[i].hoursWorked, &s[i].hourlyRate, &s[i].federalTax, &s[i].stateTax);
fscanf(f, "%.2f %.2f %.2f %.2f\n", &c[i].grosspay, &c[i].fto, &c[i].sto, &c[i].np);
}
fclose(f);
}
void savebin(struct employee s[], int n)
{
FILE *f;
f = fopen("employee.bin", "wb");
for (int i = 0; i < n; i++) {
fwrite(&s, sizeof(s[n]), n, f);
}
fclose(f);
}
void retrievebin(struct employee s[], int n)
{
FILE *f;
f = fopen("employee.bin", "rb");
for (int i = 0; i < n; i++) {
fread(&s, sizeof(s[i]), n, f);
}
fclose(f);
}
int main(){
savetext(st, c, 4);
retrievetext(st, c, 4);
printf("After reading text file");
print(st, c, 4);
savebin(st, 4);
retrievebin(st, 4);
printf("After reading bin file");
print(st, c, 4);
return 0;
}
You didn't get a warning here from this?
fscanf(f, "%.2f %.2f %.2f %.2f\n", &c[i].grosspay, &c[i].fto, &c[i].sto, &c[i].np);
fscanf() will eat any float you throw at it, specifying the %.2f format like this doesn't really work.
https://en.wikipedia.org/wiki/Scanf_format_string
Try using it like this:
fscanf(f, "%f %f %f %f\n", &c[i].grosspay, &c[i].fto, &c[i].sto, &c[i].np);
It was probably reading the file wrong, and then using the wrong line as an employee name.
PS: Your print() might have a small error:
for (int i = 0; i < 4; i++) // It should probably be i < n, instead of i < 4
And try to include an example input file, so people can test the code. At main(), there is no definition of st, so it's hard for people to see what's really happening if they can't test it themselves.

comparing floats in two structs

I have a code that reads two .txt files and puts them into structs. Then, I want to compare the x value from each file and find matches. The type of these values is floats. I keep getting incorrect matches and line numbers and I'm not sure what to do. It works for the first few but then it just says there's a match when it is only a value in one file. Everything else works fine, so if anyone has suggestions on comparing the values that would be much appreciated. Thank you.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define FLT_EPSILON 1.19209290E-07F
typedef struct fcat_s {
float x;
float y;
float a_j2000;
float b_j2000;
float mag;
} fcat_s;
typedef struct cat_s {
float num;
float x;
float y;
float xworld;
float yworld;
float flux_auto;
float mag_auto;
float awin;
float bwin;
} cat_s;
int main(void) {
float exptime = 0;
float F = 0;
float Mi = 0;
float Mcat = 0;
float FLUX_AUTO = 0;
float ZP = 0;
char fcatname[50];
char catname[50];
int fcatcount = 0;
int catcount = 0;
char fcat_c;
char cat_c;
float x;
char str[100];
int i = 0;
int j = 0;
float temp;
int match = 0;
printf("Please input the .fcat file name:\n");
scanf("%str", fcatname);
printf("Please input the .cat file name:\n");
scanf("%str", catname);
printf("Please input the exposure time:\n");
scanf("%f", &exptime);
fcat_s *f = (fcat_s *)malloc(sizeof(fcat_s));
cat_s *c = (cat_s *)malloc(sizeof(cat_s));
// .fcat file
FILE *fcat;
fcat = fopen(fcatname, "r");
if (fcat == NULL) {
printf("The input file does not exist\n");
} else {
for (fcat_c = getc(fcat); fcat_c != EOF; fcat_c = getc(fcat)) {
if (fcat_c == '\n')
fcatcount++;
if (fcatcount > 4) {
fscanf(fcat, "%f", &f[fcatcount-5].x);
fscanf(fcat, "%f", &f[fcatcount-5].y);
fscanf(fcat, "%f", &f[fcatcount-5].a_j2000);
fscanf(fcat, "%f", &f[fcatcount-5].b_j2000);
fscanf(fcat, "%f", &f[fcatcount-5].mag);
}
}
}
printf("\n");
printf("The .fcat file has %d lines. \n", fcatcount);
printf("\n");
printf("\n");
printf("FCAT CONTENTS\n");
for (i = 0; i < (fcatcount-5); i++) {
printf("%lf\t %lf\t %lf\t %lf\t %lf\n",
f[i].x, f[i].y, f[i].a_j2000, f[i].b_j2000, f[i].mag);
}
printf("\n");
printf("\n");
// .cat file
FILE *cat;
cat = fopen(catname, "r");
if (cat == NULL) {
printf("The input file does not exist\n");
} else {
for (cat_c = getc(cat); cat_c != EOF; cat_c = getc(cat)) {
if (cat_c == '\n')
catcount++;
if (catcount > 8) {
fscanf(cat, "%f", &c[catcount-9].num);
fscanf(cat, "%f", &c[catcount-9].x);
fscanf(cat, "%f", &c[catcount-9].y);
fscanf(cat, "%f", &c[catcount-9].xworld);
fscanf(cat, "%f", &c[catcount-9].yworld);
fscanf(cat, "%f", &c[catcount-9].flux_auto);
fscanf(cat, "%f", &c[catcount-9].mag_auto);
fscanf(cat, "%f", &c[catcount-9].awin);
fscanf(cat, "%f", &c[catcount-9].bwin);
}
}
}
printf("\n");
printf("The .cat file has %d lines. \n", catcount);
printf("\n");
printf("\n");
printf("CAT CONTENTS\n");
for (i = 0; (i < catcount-9); i++) {
printf("%lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\n",
c[i].num, c[i].x, c[i].y, c[i].xworld, c[i].yworld,
c[i].flux_auto, c[i].mag_auto, c[i].awin, c[i].bwin);
}
printf("\n");
printf("\n");
// searching in the files for a match
for (i = 0; (i <= (fcatcount-5)); i++){
for (j = 0; (j <= (catcount-9)); j++) {
if (fabs(f[i].x - c[j].x) < FLT_EPSILON && fabs(f[i].y - c[j].y) < FLT_EPSILON) {
printf("%f\t .fcat line: %d\t .cat line: %d\n", c[j].x, i, j);
match++;
}
}
}
printf("\n");
printf("\n");
printf("The files have %d matches. \n", match);
fclose(fcat);
fclose(cat);
free(f);
free(c);
return 0;
}
You only allocated space for one fcat_s:
fcat_s *f = (fcat_s*)malloc(sizeof(fcat_s));
But in your first loop, you are already treating f like an array:
...
fscanf(fcat, "%f", &f[fcatcount-5].x);
...
Unless I am missing something, it seems that you are reading and writing to unallocated memory. I am surprised your program doesn't segfault.

C fork and pipe add numbers from a file

Totals different for same file when executed.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_FILE_NAME 100
#define RUNS 1
int main() {
int num,i;
FILE *fp;
char*s, buf[1024];
int count =0;
char c;
char filename[MAX_FILE_NAME];
printf("Enter filename: ");
scanf ("%s",filename);
if ((fp =fopen(filename, "r")) == NULL) {
printf("Error");
exit(1);
}
fscanf(fp,"%d",&num);
for (c = getc(fp); c!= EOF; c = getc(fp))
{
if (c == '\n'){
count = count+1;
}
}
printf("%s has %d numbers \n", filename, count);
int f;
printf("Choose from the options how many processes you want to use [1,2,4]: ");
scanf("%i", &f);
printf("%i processes \n", f);
int fds[f+1][2];
int numb[count];
int x,k;
time_t start, finish;
start = time(NULL);
for(i = 0; i < RUNS; i++)
{
pipe(fds[f]);
for( x = 0; x<f; x++)
{
pipe(fds[x]);
int ind[2];
ind[0] = ((x)*(count/f));
ind[1] = ((x+1)*(count/f));
write(fds[x][1], &ind, 2* sizeof(int));
if (fork() ==0)
{
int t =0;
int ind2[2];
read(fds[x][0], &ind2, 2*sizeof(int));
for( k = ind2[0]; k<ind2[1]; k++)
{
t += numb[k];
}
write(fds[f][1], &t, sizeof(int));
exit(0);
}
}
int m, tmp, total;
total = 0;
for( m = 0; m < f; m++)
{
for( m = 0; m < f; m++)
{
read(fds[f][0], &tmp, sizeof(int));
sleep(5);
total += tmp;
}
printf("DOne calc \n");
printf("Total: %i \n", total);
}
finish = time(NULL);
float runtime = (float)((finish-start)/RUNS);
printf("runtime: %f \n", runtime);
fclose(fp);
return 0;
}
You get random result for the same input because the calculation based on uninitialized int numb[count]; values.
According to the C99 standard, section 6.7.8.10:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
Because of it int numb[count]; contains some random junk from memory. To get predictive results use explicit initialization:
#include <string.h> // memset
int numb[count];
memset (numb, 0, sizeof(numb)); // Zero-fills
Use the code bellow to put numbers from filename file into numb:
int i = 0;
char line[1024];
fseek(fp, 0, SEEK_SET);
while(fgets(line, sizeof(line), fp) )
{
if( sscanf(line, "%d", &numb[i]) == 1 ) // One number per line
{
++i;
}
}

C does not go to the next line while reading .ppm

So I have a .ppm file and the goal is to read each pixel to corresponding r[] g[] and b[] elements. The code reads the first line (idk correct or not), but it does not go any further. I'm unsure if I need these getc(fp); in order to skip spaces. Reading each line and parsing it to int is not an option. Thanks for any help.
int main(int argc, char** argv)
{
int height;
int width;
int max;
FILE *fp;
fp = fopen("vit_small.ppm", "r");
fscanf(fp, "%*[^\n]\n", NULL);
fscanf(fp, "%d %d", &width, &height);
printf("Width is %d height is %d \n", width, height);
fscanf(fp, "%d", &max);
printf("Maximum value %d \n", max);
int r [height][width];
int g [height][width];
int b [height][width];
int hist [5];
int w = 0;
int h = 0;
char buffer [1000];
for (;w<height;w++)
{
printf("Row number %d \n", w);
for (;h<width;h++)
{
fread(&r[w][h], 1, 1, fp);
printf("%d ", r[w][h]);
getc(fp);
fread(&g[w][h], 1, 1, fp);
printf("%d ", g[w][h]);
getc(fp);
fread(&b[w][h], 1, 1, fp);
printf("%d ", b[w][h]);
getc(fp);
}
getc(fp);
printf("\n");
}
int i = 0;
int j = 0;
for (;i<height; i++)
{
for (;j<width; j++)
{
printf("%d %d %d ", r[i][j], g[i][j], b[i][j]);
}
printf("\n");
}
fclose(fp);
FILE * res;
res = fopen ("Image_output.ppm", "w");
fprintf (res, "P6\n");
fprintf(res, "%d\n", width);
fprintf(res, "%d\n", height);
fprintf(res, "%d\n", max);
i = 0;
j = 0;
for(; i < height; i++)
{
for(; j < width; j++)
{
fprintf(res, "%d %d %d", r[i][j], g[i][j], b[i][j]);
}
fprintf(res,"\n");
}
return (EXIT_SUCCESS);
}
The P6 format of PPM stores each primary as a byte and there are no rows and no spaces. So if an image is 10 by 6, it will have 180 bytes (10x6x3) following the 255 and newline character. See
Wikipedia entry on PPM.

Issue with simple while loop in C terminating early

I have the following code:
//get distances
int a = -1;
int b = -1;
while ((a != 0) && (b != 0)) {
scanf("%d %d", &a, &b);
printf("The shortest path from %d to %d is %.1lf meters.\n", a, b, D[a][b]);
}
The loop seems to terminate after one input, despite the fact that a and b are not inputed as 0.
ie:
0 2
The shortest path from 0 to 2 is 237.7 meters.
Not really sure why it's doing that so any help would be appreciated.
Then it terminates
Full code in case needed
#include <stdio.h>
#include <stdlib.h>
#define INF 41e6
double** new2Ddouble(int n, int m);
void free2D(double **a);
int main() {
//get # of nodes
int size = 0;
scanf("%d", &size);
//create matrix
double **D = new2Ddouble(size, size);
//fill with inf for D[i][j]
int i;
int j;
for(i=0; i<size; i++) {
for(j=0; j<size;j++){
D[i][j] = INF;
}
}
//fill D[i][i] with INF
for(i=0;i<size;i++) D[i][i] = INF;
int exit = 0;
int I;
int J;
double d;
while(exit != 1) {
//populate values in matrix
scanf("%d %d %lf", &I, &J, &d);
if(I == 0 && J == 0 && d == 0){
//we can exit
exit = 1;
} else {
D[I][J] = d;
}
}
//calculate distances
/* Floyd-Warshall Algorithm */
int k;
for (k=0; k<size; ++k)
for (i=0; i<size; ++i)
for (j=0; j<size; ++j)
if (D[i][k]+D[k][j] < D[i][j])
D[i][j] = D[i][k]+D[k][j];
exit = 0;
//get distances
int a = -1;
int b = -1;
while ((a != 0) && (b != 0)) {
scanf("%d %d", &a, &b);
printf("The shortest path from %d to %d is %.1lf meters.\n", a, b, D[a][b]);
}
return 0;
}
double** new2Ddouble(int n, int m) {
int i;
double **ret = (double**) malloc(n*sizeof(double*));
double *a = (double*) malloc(n*m*sizeof(double));
for (i=0; i<n; ++i) ret[i] = &a[i*m];
return ret;
}
void free2D(double **a) { free(a[0]); free(a); }
scanf("%d %d", &a, &b);
In this line you are scanning values for a and b 0 and 2 respectively.
So once a new value is scanned to these variables then your while condition fails because as you have showed a is 0 and the second condition is never checked because 0 && (0|1) = 0
Once a=0 the condition fails and exits the loop.
while ((a != 0) && (b != 0))
This loop will terminate when a or b is zero and will continue when a and b are not zero. You enter a as 0 and as the condition a!=0 fails,your loop terminates.
there are a couple of problems with this line:
scanf("%d %d", &a, &b);
Note: scanf does not automatically consume white space,
so on the second iteration
the next input char is a newline.
so scanf fails
Note: all I/O statements
should have the returned value checked
to assure success of the operation
to fix those items, write it like so:
if( 2 != scanf(" %d %d", &a, &b) )
{
perror( "scanf failed" );
exit( EXIT_FAILURE );
}
the leading ' ' in the format string causes leading
white space, like the newline, to be consumed
the 'if' checks the returned value from
scanf to assure that all the input conversions were successful

Resources