I have a .csv file formatted like this:
24.74,2.1944,26.025,7.534,9.317,0.55169 [etc]
I want to move the float values into a floating point number array.
The array would look like this:
fValues[0] = 24.74
fValues[1] = 2.1944
fValues[2] = 26.025
fValues[3] = 7.534
fValues[4] = 9.317
[etc]
I have 1000 numbers to process.
What is the code to achieve this task?
This is the closest I have gotten with my code:
int main()
{
FILE *myFile;
float fValues[10000];
int n,i = 0;
myFile = fopen("es2.csv", "r");
if (myFile == NULL) {
printf("failed to open file\n");
return 1;
}
while (fscanf(myFile, "%f", &fValues[n++]) != EOF);
printf("fValues[%d]=%f\n", i, fValues[5]); //index 5 to test a number is there.
fclose(myFile);
return 0;
}
Also, when I run this code I receive exit code 3221224725.
Would this be a memory access related issue/stack overflow)?
My environment:
Sublime Text 3,
GCC compiler,
Newer windows laptop
When you read from the file, you're not skipping over the commas in the file.
The first call to fscanf reads a float via the %f format specifier. On subsequent reads, the file pointer is at the first comma and doesn't go past that because you're still trying to read a floating point number.
You need to add a separate call to fscanf inside the loop to consume the comma:
while (fscanf(myFile, "%f", &fValues[n++]) == 1) {
fscanf(myFile, ",");
}
Also, you're not initializing n:
int n,i = 0;
When you then attempt to increment it, thereby reading an uninitialized value, you invoke undefined behavior. Initialize it like this:
int n = 0, i = 0;
Related
I need to access the values from my txt file but I cannot use fopen or fclose or fsacnf. I need to use ./a.out<text.txt
the values are: 1,5,6,15,24,56,34,12,34.
#include <stdio.h>
#define SIZE 20
int input[SIZE];
int main()
{
int count;
for(int i = 0; i < SIZE; ++i)
{
printf("%d\n",count);
count++;
}
return 0;
}
If you're using input redirection, then they'll be available on the input stream, not via a file handle you have to open.
Hence you can use scanf to get them. Assuming they're just a sequence of integers separated by white space(a), this will be a good start:
int value; // Need variable.
while (scanf("%d", &value) == 1) { // Returns 1 if successful.
printf("Got %d\n", value); // Progress messages.
}
(a) I'm assuming here that the commas in your number list are merely separators in the question to distinguish the numbers from each other (i.e., they're not in the file itself).
If they actually exist in the file, then they'll need to be consumed as well.
Absolutely new to C. I am trying to write a program to either read integers contained in a file (passed as arg) or from stdin. First number read is supposed to indicate the array size.
I have something but it throws segmentation fault. Please help.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]) {
FILE *f;
int n, numbers[n], firstNum;
if (argc != 0)
{
f = fopen(argv[1], "r");
fscanf(f, "%d", & firstNum);
int numbersArray[firstNum];
for (int i = 0; i < firstNum; i++)
{
fscanf(f, "%d", &numbersArray[i]);
}
for (int i = firstNum; 0 <= i; i--)
{
printf("Numbers: %d\n\n", numbersArray[i]);
}
fclose(f);
}
else
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
fscanf(stdin, "%d", &numbers[i]);
printf("%d\n", i, numbers[i]);
}
return 0;
}
First off always initialize your variables like kaylum and myself mentioned in the comments.
Unlike some other programming languages C doesn't initialize your variables for you.
Now for the question you posted, you got the idea mostly correct but there are things that i suggest you change:
int n, numbers[n], firstNum;
to
int n = 0, numbers[1000], firstNum = 0;
If you're not happy with that you could move the numbers[n] lower when n is initialized but i wouldn't advise that.
Instead of that, since you're learning C have a look at dynamically allocated arrays using pointers.
Some links to help you understand pointers:
https://www.cprogramming.com/tutorial/c/lesson6.html
https://www.tutorialspoint.com/cprogramming/c_pointers.htm
Next have a look at your fopen it has a return value that tells you if it succeeded to open the file you requested.
So you can add:
f = fopen(argv[1], "r");
if (f == NULL)
{
printf("File Not Found!");
return -1;
}
Modify the condition to suite the way you want to handle that error.
When you're reading the file the user specifies the size of the array you're reading but you should consider the fact that the file may not contain the exact amount of elements.
The function that you are using fscanf has a way to tell you that and that's it's return value.
It will return EOF which is a special value that translates to End Of File.
Consider modifying your fscanf to this:
if (fscanf(f, "%d", &firstNum) == EOF)
{
printf("ERROR");
}
Or if you're in a for loop put break
The last thing is that you don't have to explicitly use fscanf for stdin, the user has specified that he will input it through stdin so you can just as well use scanf.
Hope this helps and good luck with your future C endeavors.
Ive just started c programming.
I would like to read a file of ints which are in a text file in the format
int1(space)int2(space)int3
int4(space)int5(space)int6
int7(space)int8(space)int9
data file example (actually has 25 million lines)
1000002 1 55
1000002 1000006 33
1000002 1000007 8
i am trying to read the numbers and each line i would like to store the 3 ints into a separate variable so i can create a struct with 3 ints per struct. I have a function to create the structs however i don't know how to read the numbers in line by line then assign each 3 ints into a temp variable.
I will be using dynamic allocation to store the structs so just array as temp storage
FILE *fp = fopen("uboss.txt", "r");
//char text[255];
int i = 1;
int a = 1;
int numberArray[9999];
int tmpUI = 0;
int tmpAI = 0;
int tmpPC = 0;
if (fp == NULL)
{
printf("Error Reading File\n");
exit (0);
}
while (!feof(fp))
{
fscanf(fp, "%d ", &numberArray[i]);
printf("Number %d: %d\n",i,numberArray[i]);
tmpUI = numberArray[a];
tmpAI = numberArray[a+1];
tmpPC = numberArray[a+2];
i++;
}
fclose (fp);
You are not the only one asking about this assignment. Try a simpler approach:
In a loop, read each line with fgets(),
Then scan the line for 3 integers with sscanf(str, "%d%d%d", &a, &b, &c); and check the return value, it should be 3.
Finally deal with the values: store them, test them, output them...
There might be extra problems to watch for:
What if the input file contains non numeric values?
What if the values are larger than can fit in the int type.
Its very simple if you know how fscanf works (and returns):
while( fscanf(fp, "%d%d%d", &tmpUI, &tmpAC, &tmpPC) == 3 )
{
...
}
so I have this file called "score.txt" with contents
NAME
20
NAME2
2
And I'm using this code but it gets an error and I have no idea on how to put the integers from the file in an array.
int main(){
FILE* file = fopen ("score.txt", "r");
int i = 0;
fscanf (file, "%d", &i);
while (!feof (file))
{
printf ("%d ", i);
fscanf (file, "%d", &i);
}
fclose (file);
system("pause");
}
I'm only self learning and i've been trying to figure this out for 2hours already
The problem with using fscanf for input where some lines will fail the format is that the file will not be advanced per iteration of the while loop, so you get stuck.
You can get a solution by using fgets to grab the data and sscanf to grab the number:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void) {
int i = 0;
int ret = 0;
char buf[50];
FILE *file = fopen("score.txt", "r");
if (file == NULL) {
fprintf(stderr,"Unable to open file\n");
exit(1);
}
while (fgets(buf,sizeof(buf),file)) {
ret = sscanf(buf,"%d",&i);
if (ret == 1) { // we expect only one match
printf("%d\n", i);
} else if (errno != 0) {
perror("sscanf:");
break;
}
}
fclose(file)
return(0);
}
This will output, for your input:
20
2
We check the output of sscanf as it tells us if the format has been matched correctly, which will only happen on the lines with integer, and not the 'NAME' lines. We also check for 'errno' which will be set to non-zero if sscanf encounters an error.
We used char buf[50]; to declare a char array with 50 slots, which fgets then uses to store the line its reading; however if the line is more than 50 chars in length it will be read in 50 char chunks by fgets, and you may not get the results you desire.
If you wish to store the integers you read into an array, you'll have to declare an array, then on each read assign a slot in that array to the value of the int you read i.e. int_array[j] = i (where j will have to change with each slot you use). I'll leave it as an exercise to implement this.
I posted a problem yesterday regarding a certain segment of my code. The aim was to basically scan in data values from a .dat file into an array, print the values whilst also counting how many values were in the file.
Sounds pretty simple, but my program only seemed to print a certain number of the values. More specifically, of a data file containing over 300000 values, it would only print the last 20000 and nothing else.
So I left it, finished the rest of my code and now it's the last part I have to sort. I've made a few changes and tried actually printing an output .dat file now so I can see what I'm getting. The code is below by the way.
Initally I assumed perhaps it was something related to the memory allocation of my array (was getting a segmentation error? when putting the whole code together) so I created an external function that counted the number of values instead (that works).
My only problem now is that it still only chooses to print 20000 values and then the rest are 0s. I was thinking perhaps it had something to do with the type but they all contain 7 dps in scientific notation. Here's a sample of some of the values:
8.4730000e+01 1.0024256e+01
8.4740000e+01 8.2065599e+00
8.4750000e+01 8.3354644e+00
8.4760000e+01 8.3379525e+00
8.4770000e+01 9.8741315e+00
8.4780000e+01 9.0966478e+00
8.4790000e+01 9.4760274e+00
8.4800000e+01 7.1199807e+00
8.4810000e+01 7.1990172e+00
Anyone see where I'm going wrong? I'm sorry for the long question, it's just been bugging me for the last day or so and no matter what I change nothing seems to help. Any kind of input would be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
int count(int);
const char df[]="data_file.dat";
const char of[]="output_file.dat";
int main(int argc, char *argv[])
{
FILE *input, *output;
int i, N;
float *array;
N = count(i);
input = fopen(df, "r");
output = fopen(of, "w");
array = (float*)malloc(N*sizeof(float));
if((input != (FILE*) NULL) && (output != (FILE*) NULL))
{
for(i = 0; i < N; i++)
{
fscanf(input, "%e", &array[i]);
fprintf(output, "%d %e\n", i, array[i]);
}
fclose(input);
fclose(output);
}
else
printf("Input file could not be opened\n");
return(0);
}
int count(int i)
{
FILE *input;
input = fopen(df, "r");
int N = 0;
while (1)
{
i = fgetc(input);
if (i == EOF)
break;
++N;
}
fclose(input);
return(N);
}
Your biggest problem is that count() doesn't count float values; it counts how many characters are in the file. Then you try to loop and call fscanf() more times than there are values in the file. The first times, fscanf() finds a float value and scans it; but once the loop reaches the end of file, fscanf() will be returning an EOF status. It seems possible that fscanf() will set the float value to 0.0 when it returns EOF.
I suggest you rewrite so that you don't try to pre-count the float values. Write a loop that just repeatedly calls fscanf() until it returns an EOF result, then break out of the loop and close the files.
P.S. If you are going to write a function like count(), you should pass in the filename as an argument instead of hard-coding it. And your version of count() takes an integer argument but just ignores the value; instead, just declare a temp variable inside of count().
EDIT: Okay, here is a complete working program to solve this problem.
#include <stdio.h>
int
main(int argc, char **argv)
{
FILE *in_file, *out_file;
unsigned int i;
if (argc != 3)
{
fprintf(stderr, "Usage: this_program_name <input_file> <output_file>\n");
return 1; // error exit with status 1
}
in_file = fopen(argv[1], "r");
if (!in_file)
{
fprintf(stderr, "unable to open input file '%s'\n", argv[1]);
return 1; // error exit with status 1
}
out_file = fopen(argv[2], "w");
if (!out_file)
{
fprintf(stderr, "unable to open output file '%s'\n", argv[2]);
return 1; // error exit with status 1
}
for (i = 0; ; ++i)
{
int result;
float x;
result = fscanf(in_file, "%e", &x);
if (1 != result)
break;
fprintf(out_file, "%d %e\n", i, x);
}
return 0; // successful exit
}
Note that this version doesn't need to allocate a large array; it just needs a single temporary float variable. Maybe your program will need to store all the float values. In that case, write a count() function that uses a loop similar to the above loop, using fscanf() to count float values.
Also note that this program checks for errors after calling fopen() and fscanf().
You are allocating far more floats in memory (N) than you need because your N is the number of characters in the file, not the number of values in it.
Also, how did you determine that there are 300000 values in the file?