reading a dat file and adding numbers to array - c

My program requires me to read a dat file with a list of numbers. My goal is to get each number and add them to an array. The file has around 100 numbers in this format:
1
2
3
(styling is a bit off sorry ;[ )
so far i have
int main()
{
double prices[1000];
int count,price;
FILE *file;
file = fopen("price.dat","r");
if(file == NULL)
{
printf("Error: can't open file to read\n");
}
else
{
printf("File prices.dat opened successfully to read\n");
}
if (file){
while (fscanf(file, "%d", &price)!= NULL){
count++;
prices[count]=price;
}
}
fclose(file);
}
Problem is that it continues adding the last number continuously. Any help?

You have several problems in your code. To name a few:
fscanf doesn't return a pointer so you shouldn't be comparing it with NULL. All scanf functions returns an integer which can be positive, zero or negative.
You don't initialize count so it will contain a seemingly random value.
Indexing of arrays starts a zero, so you should not increase the array index count until after the assignment.
The actual problem with not wanting to stop is because of the first point.

#include <stdio.h>
#include <string.h>
#define PRICES_LIST_MAX 1000
#define PRICES_FILE "price.dat"
int main()
{
double prices[PRICES_LIST_MAX];
int count = 0;
int i = 0;
FILE *file;
file = fopen(PRICES_FILE,"r");
if(!file)
{
perror("Error opening file");
return -1;
}
memset(prices, 0, sizeof(prices));
while (!feof(file) /* Check for the end of file*/
&&(count < PRICES_LIST_MAX)) /* To avoid memory corruption */
{
fscanf(file, "%lf", &(prices[count++]));
}
fclose(file);
/* Print the list */
printf("Prices count: %d\n", count);
for(i = 0; i < count; i++)
{
printf("Prices[%d] = %lf\n", i, prices[i]);
}
return 0;
}

Related

Write a program in C that reads up to 100 integers from a file, where the first value from the file is the number of subsequent values in the file

Write code that reads a number of values, interpreted as integers, from a file named “mtData.txt”, where the first number tells how many subsequent numbers there are, and there will never be more than 100 integers.
I'm new to C, coming from a background in Java. I wrote the following, producing an infinite loop that prints the obvious statements and an address not the values from the file.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(){
FILE *fp = (FILE*) 0;
int c = -1;
fp = fopen("myInput.txt", "r");
if(fp == NULL){
puts("Error accessing file");
return(-1);
}
bool doneReading = false;
int numbers[100];
while (!doneReading){
puts("Reading now");
c = fscanf(fp, "%d", numbers);
printf("Read %d items\n", c);
if(feof(fp)){
doneReading = true;
}
printf("%d\n", numbers);
fclose(fp);
}
}
A possible approach (take a look at how the loop is implemented):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(void) {
FILE* fp = fopen("myInput.txt", "r");
if (fp == NULL) {
puts("Error accessing file");
return 1;
}
// this is the array that will contain the numbers
int numbers[100];
// this is the number of integers that the file contains
int max_numbers;
// this is the number of integers that we have actually read from the file
int counter = 0;
// max_numbers is actually the first integer that we find in the file
if (fscanf(fp, "%d", &max_numbers) != 1 || max_numbers < 0 || max_numbers > 100) {
printf("ERROR\n");
return 1;
}
printf("Max numbers: %d\n", max_numbers);
// now that we know the number of integers, we can loop to read them all
while (counter < max_numbers) {
if (fscanf(fp, "%d", &numbers[counter]) != 1) {
printf("ERROR\n");
return 1;
}
counter += 1;
}
// now we print all the numbers that we have read
for (int i = 0; i < counter; i += 1) {
printf("Number #%d = %d\n", i, numbers[i]);
}
fclose(fp);
return 0;
}
I used fscanf(fp, "%d", &var) != 1 to put the number inside var and check that everything went well (fscanf() will return the number of arguments successfully assigned, in this case only %d).
EDIT:
The previous code does not check if the file contains more data than necessary (that would also mean that the file is not valid), so it just ignores that extra data (thanks #chux for pointing it out).
Also note that fscanf() will not detect integer overflows, so in the future you may want to look at alternative approaches for integer parsing (e.g.: strtol()).

Trying to add a text file into an array in C

I am trying to take 500 numbers in this text file and store them into an array, it keeps giving me random numbers that aren't in my text file at all. I've also changed a few things and it is saying that there is conflicting types for my fp_read
#include<stdio.h>
int ch;
int X[500];
FILE*fp_read = NULL;
fp_read = fopen("random_numbers.txt","r");
int main()
{
for(i=0;i<499;i++)
{
if(ch==EOF)
{
printf("End of File\n");
}
else
{
ch = (fgetc(fp));
X[i]=ch;
printf("%d,"X[i]);
}
}
return 0;
}
sorry for the quick answer but try to use atoi or strtol to convert the character to integer or add -48 because '0' in ascii is 48
You are interpreting the character codes of the digits used to encode the textual numbers, which is probably not at all what you want. For instance in UTF-8 the number "12" consists of the two code points 1 and 2, which encode as the two 8-bit values 49 and 50.
For line-based input, it's almost always best to read whole lines into a suitably large buffer, then parse that. That is more robust than parsing the stream itself.
Something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * const fp = fopen("random-numbers.txt", "rt");
if(fp == NULL)
{
fprintf(stderr, "**File open failed\n");
exit(1);
}
int numbers[500];
int index = 0;
char line[1024];
while(fgets(line, sizeof line, fp) != NULL)
{
if(index >= sizeof numbers / sizeof *numbers)
break;
numbers[index++] = (int) strtol(line, NULL, 10);
}
printf("Read these numbers:\n");
for (int i = 0; i < index; ++i)
printf("%d: %d\n", i, numbers[i]);
return 0;
}

Can't read a single double value from a file (C)

I am having trouble reading in just a single data point from a file. It is supposed to be able to read two columns of data (such as x and y values), but I found out my code cannot even read a single value of double precision. Any help would be appreciated.
The file is at D:\test.txt
and there is a single value of 1.11111.
Enter the location of file (text file) of the airfoil coordinates: D:\test.txt
There are 1 lines
The amount of data in x and y is 1 points and 1 points.
failed to read.
* Process returned 1 *
Press any key to continue...
That was my input.
/*
Purpose:
Create a program that can take in a list of data points that represents an airfoil from some file.
Then through the use of spline function, spline the data points for interpolation then go on to plotting them.
With these data points, use the Vortex Panel Method to obtain coefficients of lift, pressure, and tangential velocity.
Then after these are calculated, plot each with respect to the splined x data points.
*/
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#define LEN 12
int countlines(FILE *fp);
int main (void)
{
char airfoil[500];
double *x_data = NULL;
double *y_data = NULL;
FILE *pfile = NULL;
int line_count = 0;
double test = 0.0;
printf("Enter the location of file (text file) of the airfoil coordinates: ");
scanf("%s", airfoil);
if(fopen_s(&pfile, airfoil, "r"))
{
printf("Error opening the file for reading the data. Program terminated.\n");
exit(1);
}
line_count = countlines(pfile);
printf("There are %d lines\n", line_count);
x_data = realloc(x_data, line_count*(sizeof(double)));
y_data = realloc(y_data, line_count*(sizeof(double)));
if((!x_data) || (!y_data))
{
printf("Memory allocation has failed. Exiting...\n");
exit(1);
}
printf("The amount of data in x and y is %zu points and %zu points.\n", (sizeof(x_data)/sizeof(double)), (sizeof(y_data)/sizeof(double)));
if(EOF == fscanf_s(pfile, "%lf", &test))
{
printf("failed to read.\n");
exit(1);
}
//for(int i = 0; i < line_count; i++)
//{
//fscanf(pfile, " %lf", &x_data[i]);
//}
printf("The x-data are %lf!\n", test);
//for(int i = 0; i < line_count; i++)
//{
//printf("%.2lf", x_data[i]);
//printf("\n");
//}
return 0;
}
int countlines(FILE *fp)
{
int lines = 0;
char str[LEN];
while(!feof(fp))
{
if (fgets(str, LEN, fp) != NULL);
{
lines++;
}
}
return lines;
}
countlines just brought the file pointer to the end of file. Before you can read anything, you must first rewind the file to the beginning:
fseek(pfile,0,SEEK_SET);
You can do ths in countlines().
See also the comments, that spot some more errors.

I cannot read more than a 49 structs array from a file

I've got this code. When I compile and execute this, no error is displayed, but, since the 50th element until the last one, the values are out of the interval of rand() (which is, i think, from 0 to 32767). It was quite unexpected, because the program continues without showing any writing-error message.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define MAX 100
using namespace std;
struct num {
int val;
};
int main() {
FILE *f, *g;
num data[MAX];
f = fopen("file1.txt", "w");
if(f == NULL) {
printf("Error\n");
exit(0);
} else {
for(int i = 0; i < MAX; i++) {
data[i].val = rand();
}
fwrite(data, sizeof(num), MAX, f);
if(ferror(f)) {
exit(0);
}
fclose(f);
}
num data1[MAX];
g = fopen("file1.txt", "r");
if(g == NULL) {
exit(0);
} else {
fread(data1, sizeof(num), MAX, g);
if(ferror(g)) {
printf("Error\n");
exit(0);
}
fclose(g);
for(int i = 0; i < MAX; i++) {
printf("val %d : %d\n", i+1, data1[i].val );
}
}
}
I Think issue with the file opening mode, you have chosen text mode which is system dependent, change it to binary mode and everything would work as expected.
Text mode is depending on the environment where the application runs, some special character conversion may occur in different input/output text according to a system-specific text . Although on same environments no conversions will occur for binary file mode. Binary mode save and read your data without any conversion.
There is no problem with your code.
Add the following at the end of main to check any mismatched values.
for (int i = 0; i < MAX; ++i )
{
if ( data[i].val != data1[i].val )
{
printf("The %d-th value does not match after reading from file.\n", i);
}
}

Sorting numbers from queue in C without using a file

I have a queue with int numbers, the goal is to print all elements sorted. First, I save all numbers in a txt file, and then I use the shell command "sort" to print all of them sorted. It's possible to do this in a cleaner way? (without using files, and if it's possible without system(...);)
This is the code:
...
FILE* fp=fopen("numbers.txt","w+");
printf("\n");
while (!empty(&my_queue)) //while queue is not empty
{
elem = first(&my_queue); //first() gets and deletes first element of queue
fprintf(fp,"%d\n", elem->number);
}
fclose(fp);
system("sort -n < numbers.txt");
remove("numbers.txt");
}
Thanks!
Supposing your numbers are floats listed separate lines of your file:
Create an array of float. If your don't know how many numbers you have, use a very large array (Note: in the example below, I created an array number_array of size 100)
Read your file
For each line of your file, store the number in the array you created in step 1
After reading the whole file, sort the array. Note that in the example below, I use the function qsort to sort the array (see manual with command man qsort ;) )
Write the content of your sorted array in your file
Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LINE_SIZE 1024
// Comparison function used for sorting
int compare (const void * a, const void * b)
{
float fa = *(float*) a;
float fb = *(float*) b;
return (fa > fb) - (fa < fb);
}
// -------------------------------------------------------------
int main()
{
FILE *f;
char line[LINE_SIZE], *p;
int i = 0, j;
// YOUR NUMBER ARRAY
float number_array[100];
// Open file
if (!(f = fopen("numbers.txt", "r"))) {
fprintf(stderr, "Unable to open file argument\n");
return 1;
}
// Read lines from file
while (fgets(line, LINE_SIZE, f)) {
// You may want to remove the trailing '\n'
if ((p = strchr(line, '\n'))) { *p = '\0'; }
// Skip empty lines
if (line[0] == '\0') { continue; }
// Adding number to array
number_array[i] = atof(line);
i++;
}
// Closing file
fclose(f);
// Sorting array
qsort (number_array, i, sizeof(float), compare);
// Displaying result 8-)
// for (j=0; j<i; j++)
// {
// printf("%0.2f ", number_array[j]);
// }
// printf("\n");
// Writing sorted result to file
if (!(f = fopen("numbers.txt", "w"))) {
fprintf(stderr, "Unable to open file argument\n");
return 1;
}
for (j=0; j<i; j++)
{
fprintf(f, "%0.2f\n", number_array[j]);
}
fclose(f);
return 0;
}

Resources