Reputation: 63
So I'm trying to print my my data from a file that was already given to me. In our data most of the numbers have 9 decimal places. A starter code was given to me by my teacher and when I try to print the data it only prints up to 6 decimal places. So the last 3 digits don't show up in the output. Also I have tried to write the number of decimal places like %.9f
but surprisingly the last three digits are different. For example the number in my data is 1.900195512
while the printed number (set to 9 decimal places) is 1.900195479
.
My code is:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
// Declare constants
// Name of file that stores our raw data
#define FILE_NAME "data_1.csv"
// Data size
#define MAX_ROWS 20
#define MAX_COLUMNS 20
// Main entry point for the program
int main(void) {
// Decalred variables
int rowIndex = 0;
int columnIndex = 0;
float rawData[MAX_ROWS][MAX_COLUMNS]; // 2-dimensional array to store our
raw data
// Misc variables used for reading the data from the file
float tempfloat = 0.0F;
float tmp = 0.0F;
char newline = ' ';
// ----------------------------------------------------------------------
// Open the file for reading
FILE *infp;
infp = fopen(FILE_NAME, "r");
// Check for errors and exit if found
if (infp == NULL) {
printf("Error: failed to open %s for reading\n", FILE_NAME);
return(1);
}
// Read the file into the data structure
for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
// Read up until the last value
for (columnIndex = 0; columnIndex < MAX_COLUMNS - 1; columnIndex++) {
if (fscanf_s(infp, "%f,", &tempfloat) != EOF) {
rawData[rowIndex][columnIndex] = tempfloat;
} else {
printf("Error: incorrect file format at row %d, col %d.\n", rowIndex + 1, columnIndex + 1);
return(1);
}
}
// Read the last value and the newline char
if (fscanf_s(infp, "%f%c", &tempfloat, &newline) != EOF) {
// Check if the last character in the line was a \n otherwise an error occured.
//Xiao: I have added newline != '\n'
if (newline != '\0' && newline != '\r' && newline != '\n') {
printf("Error: incorrect file format at line %d. did not find a newline.\n", rowIndex + 1);
return(1);
} else {
rawData[rowIndex][columnIndex] = tempfloat;
}
// Reset the character before the next read.
newline = ' ';
}
}
// ----------------------------------------------------------------------
// Print out the rawdata array
printf(" --- RAW DATA ---\n");
for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
// Read up until the last value
for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) {
printf("%.9f ", rawData[rowIndex][columnIndex]);
}
printf("\n");
}
// Exit
return (0);
}
Upvotes: 2
Views: 449
Reputation: 5880
float
is not accurate after 7 places. Use double
instead
#include <stdio.h>
int main()
{
float f;
double d;
scanf("%f",&f);
scanf("%lf",&d);
printf("%.9f\n",f);
printf("%.9lf\n",d);
return 0;
}
Input:
0.123456789 // float variable i.e. f
0.123456789 // double variable i.e. d
Output:
0.123456791 // float precision
0.123456789 // double precision
Upvotes: 1
Reputation: 144961
The float
type does not have enough precision for 9 accurate decimal places. You should use the double
type, which you can scan with %lf
.
Also do not compare the return value of fscanf()
to EOF
to detect failure, invalid input may cause 0
to be returned. Just verify the number of successful conversions returned by fscanf()
.
Here is a modified version:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
// Declare constants
// Name of file that stores our raw data
#define FILE_NAME "data_1.csv"
// Data size
#define MAX_ROWS 20
#define MAX_COLUMNS 20
// Main entry point for the program
int main(void) {
// Decalred variables
int rowIndex = 0;
int columnIndex = 0;
double rawData[MAX_ROWS][MAX_COLUMNS]; // 2-dimensional array to store our
raw data
// Misc variables used for reading the data from the file
double tempfloat = 0.0;
double tmp = 0.0;
char newline;
// ----------------------------------------------------------------------
// Open the file for reading
FILE *infp;
infp = fopen(FILE_NAME, "r");
// Check for errors and exit if found
if (infp == NULL) {
printf("Error: failed to open %s for reading\n", FILE_NAME);
return(1);
}
// Read the file into the data structure
for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
// Read up until the last value
for (columnIndex = 0; columnIndex < MAX_COLUMNS - 1; columnIndex++) {
if (fscanf_s(infp, "%lf,", &tempfloat) == 1) {
rawData[rowIndex][columnIndex] = tempfloat;
} else {
printf("Error: incorrect file format at row %d, col %d.\n", rowIndex + 1, columnIndex + 1);
return 1;
}
}
// Read the last value and the newline char
if (fscanf_s(infp, "%lf%c", &tempfloat, &newline) == 2) {
// Check if the last character in the line was a \n otherwise an error occured.
//Xiao: I have added newline != '\n'
if (newline != '\r' && newline != '\n') {
printf("Error: incorrect file format at line %d. did not find a newline.\n", rowIndex + 1);
return 1;
} else {
rawData[rowIndex][columnIndex] = tempfloat;
}
}
}
// ----------------------------------------------------------------------
// Print out the rawdata array
printf(" --- RAW DATA ---\n");
for (rowIndex = 0; rowIndex < MAX_ROWS; rowIndex++) {
// Read up until the last value
for (columnIndex = 0; columnIndex < MAX_COLUMNS; columnIndex++) {
printf("%.9f ", rawData[rowIndex][columnIndex]);
}
printf("\n");
}
// Exit
return 0;
}
Upvotes: 2
Reputation: 84569
You can break your problem down into a much more concise example to help isolate the problem. You are attempting to get 9-digit precision out of a type float
, that is only good for 6-7. To improve your accuracy, you need to use type double
instead.
When you read any user input always, always validate the return of the function used, and any constraints on the value (none in you case).
A short implementation correcting the issue could be:
#include <stdio.h>
int main (void) {
double d = 0.0;
printf ("Enter value: ");
if (scanf ("%lf", &d) == 1)
printf ("Your value : %.9f\n", d);
return 0;
}
Example Use/Output
$ ./bin/scanf_double
Enter value: 1.900195512
Your value : 1.900195512
Look over the answers and comments and let me know if you have further questions.
Upvotes: 1