How can I get the values in my file without fopen - c

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.

Related

C fgets giving unexpected result

I'm doing Advent of Code 2022, and I'm hitting a strange bug for day 1 (https://adventofcode.com/2022/day/1) which I need help with please.
Currently, I'm trying to parse a text file which has groups of numbers (https://adventofcode.com/2022/day/1/input) and output the results to the screen. Code as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define IN_FILE "input.txt"
#define MAX_LINE_LEN 20480
int main(int argc, char *argv[])
{
// Variable declaration
char line[MAX_LINE_LEN];
int counter = 0;
int elfno = 0;
FILE *fd;
// Create "Key Value pair" struct. Use ints for both vars as we need to perform arithmetic on the values.
struct kv_store
{
int key;
int value;
};
struct kv_store kv[counter];
//struct kv_store kv_total;
// Open file
fd = fopen(IN_FILE, "r");
if (fd == NULL)
{
// File does not exist. Exit
fprintf(stdout, "\n[*]%s not found in current working directory.", IN_FILE);
return -1;
}
// Iterate through file line by line. Place lines into kv[n].value with kv[n].key as the elf number (elfno). Increment elfno once a blank line is found.
while(fgets(line, MAX_LINE_LEN, fd) != NULL)
{
if(strlen(line) == 1)
{
elfno ++;
continue;
}
else
{
kv[counter].key = elfno;
sscanf(line, "%d", &kv[counter].value);
//kv[counter].value = strtol(line, NULL, 0);
counter ++;
continue;
}
}
for(int i=0;i < counter;i++)
{
fprintf(stdout, "Iteration: %d - Elf: %d holds: %d \n", i, kv[i].key, kv[i].value);
}
// TODO: Upon EOF, we can iterate through kv. If elfno for next value in kv hasn't changed, add value to kv_total[elfno].value. If it does change, move on to the next efls values.
// TODO: Once complete, iterate through kv_total and find the largest number, print to screen.
return 0;
}
Everything seems to be working ok, however on the 4th iteration of the while loop which reads the value 6086 from the input, I get a garbage result. I should be seeing Elf: 1 holds: 6086. The remaining iterations give the correct output (sample screenshot below).
Using my very limited knowledge of gdb and debugging, I've looked at the line variable during runtime and can see that the variable is being modified only when line contains the value 6086 partway through the iteration (screenshot below).
Checks carried out so far:
Used a hex editor to confirm there is no rogue encoding within the input file
Tried using strtol instead of of sscanf
Tried to use malloc() and free() to clear the line variable at the end of each iteration
Any help on this would be much appreciated.

fscanf consumes first letter in file. How do I fix it?

I am making a program for a class that reads the contents of a .csv file. I am using a while loop inside of a for loop to scan the contents into two separate arrays, and when it prints the contents, everything is right, except it is missing the first letter in the file. We are not allowed to use any functions from the library except what is permitted.
Code in question:
void readFile(FILE *fptr, int size)
{
int i, a;
a = size / 2;
printf("number of lines in readFile is %d:\n", size);
double y[50];
char x[50];
for (i = 0; i < a; i++)
{
while (fscanf(fptr,"%c,%lf,", &x[i], &y[i]) ==2);
}
printf("%c, %.2lf: ", x[0], y[0]);
//a loop to make sure it scanned properly by displaying array contents
for (i = 0; i < a; i++)
{
printf("%c, %.2lf:\n", x[i], y[i]);
}
}
I tried with no luck to !feof(fptr), != EOF, but these are not supposed to be used in the intro class I am taking. I am out of ideas to fix it.
This is the output of the program above:
number of lines in readFile is 4:
, 20.00:
, 20.00:
E, 30.00:
number of lines is 4:
A few issues ...
The fscanf format is wrong. It needs a leading space to skip over newlines.
Unless you intend to operate on the data read in readFile (vs. passing it back to caller), having function scoped x and y arrays will go out of scope when the function returns.
The caller of readFile should pass the maximum array count but let the function determine the actual number of entries.
Whenever I see two or more "parallel" arrays [indexed by the same variable], I would use a struct. Particularly for .csv data.
.csv files are of the form: a,b\nc,d\n and not a,b,\nc,d,\n so the trailing , in the fscanf is incorrect.
Using nested loops for the data input doesn't work.
No need for feof. Just loop until the fscanf return is not 2.
Here is the corrected code. It is annotated:
#include <stdio.h>
#include <stdlib.h>
// data for single .csv line
struct data {
char x;
double y;
};
// readFile -- read in .csv file
// RETURNS: count of records/lines read
size_t
readFile(FILE *fptr, struct data *arr, size_t size)
// fptr -- open file stream
// arr -- pointer to data array
// size -- maximum number of elements in arr
{
int count = 0;
while (1) {
// check for overflow of array
if (count >= size) {
fprintf(stderr,"readFile: too much data for array\n");
exit(1);
}
// point to current struct/record
struct data *cur = &arr[count];
// read in the .csv line -- stop on error or EOF
if (fscanf(fptr, " %c,%lf", &cur->x, &cur->y) != 2)
break;
// advance the count of the number of valid elements
++count;
}
return count;
}
int
main(int argc,char **argv)
{
struct data arr[50];
// skip over program name
--argc;
++argv;
if (argc != 1) {
printf("wrong number of arguments\n");
exit(1);
}
// open the input file
FILE *fptr = fopen(argv[0],"r");
if (fptr == NULL) {
perror(argv[0]);
exit(1);
}
// read in the data lines
size_t count = readFile(fptr,arr,sizeof(arr) / sizeof(arr[0]));
fclose(fptr);
// print the array
for (size_t idx = 0; idx < count; ++idx) {
struct data *cur = &arr[idx];
printf("%c, %.2f:\n",cur->x,cur->y);
}
return 0;
}
Here is the sample input I used to test the program:
J,23
D,37.62
F,17.83
Here is the program output:
J, 23.00:
D, 37.62:
F, 17.83:

How to move values from a CSV file to a float array?

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;

Reading from a file into 2D array returns wrong values in C?

so I have this simple program which reads values from a file and then I just want to print them to the screen. The problem occurs when array is printed to the screen. It adds some random numbers in the middle of the array. Does anybody have an idea what's the problem?
Here is the output:
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define MAXROW 10
#define MAXCOL 12
int main(void) {
int i,j;
char numbers[MAXROW][MAXCOL];
FILE *file; /* FILE pointer */
file = fopen("data.txt", "r"); /* open a text file for reading */
for(i=0;i<MAXROW;i++){
for(j=0;j<MAXCOL;j++){
fscanf(file, "%d\t", &numbers[i][j]);
if(numbers[i][j] == '\n')
i++;
}
}
for (i=0; i<MAXROW; i++) {
printf("\n");
for (j=0; j<MAXCOL; j++) {
printf("%d ", numbers[i][j]);
}
}
fclose(file);
return 0;
}
Here is my data.txt file:
Change your loop to
for(i=0;i<MAXROW;i++)
for(j=0;j<MAXCOL;j++)
fscanf(file, "%d%*c", &numbers[i][j]);
numbers[i][j] will never get the value of '\n' since it only matches integers when you use %d
Instead use fgets() to get one line at a time,
and then use sscanf() to get every integer on that line.
In your code I doubt if you are hitting this condition if(numbers[i][j] == '\n').
So, you are looping to max values & storing junk values.
read line by line & parse it for individual numbers.

Program not accepting all values from file

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?

Resources