Getting data from a .txt file in C - c

I'm new to C and I have to read data from a file, and I need to store that data in an array. I'm using FILE *fptr; fptr = fopen(¨filename.txt¨, ¨r¨) to read and fscanf(fptr,"%d", &num); to get the file data, however when compiling I only seem to get the memory location for it (I think? the file I'm using to try the code out has the number 5368 and I'm getting 6422296)
int main(void)
{
FILE *fptr;
fptr = fopen("example.txt" , "r");
if ((fptr = fopen("example.txt","r")) == NULL)
{
printf("Error! opening file");
exit(1);
}
int num;
fscanf(fptr,"%d", &num);
printf("VALUE OF NUM IS %d", &num);
fclose(fptr);
return 0;
}

Here a minimal example demonstrating reading a couple of numbers from filename.txt into an array num. You need to add error handling, and if you cannot fix the size (LEN) then either calculate it by figuring out how numbers is in the file, or realloc the size of the num array as needed:
#include <stdio.h>
#define LEN 2
int main() {
FILE *fptr = fopen("./filename.txt", "r");
int num[LEN];
for(int i = 0; i < LEN; i++) {
fscanf(fptr, "%d", num + i);
printf("%d\n", num[i]);
}
fclose(fptr);
}

Related

How to read the content from the second line onwards on a .txt file on C

I need help to read the numbers of a .txt file and put them in an array. But only from the second line onwards. I'm stuck and don't know where to go from the code that i built.
Example of the .txt file:
10 20
45000000
48000000
56000000
#define MAX 50
int main (void){
FILE *file;
int primNum;
int secNum;
int listOfNumers[50];
int numberOfLines = MAX;
int i = 0;
file = fopen("file.txt", "rt");
if (file == NULL)
{
printf("Error\n");
return 1;
}
fscanf(file, "%d %d\n", &primNum, &secNum);
printf("\n1st Number: %d",primNum);
printf("\n2nd Number: %d",secNum);
printf("List of Numbers");
for(i=0;i<numberOfLines;i++){
//Count the number from the second line onwards
}
fclose(file);
return 0;
}
You just need a loop to keep reading ints from file and populate the listOfNumers array until reading an int fails.
Since you don't know how many ints there are in the file, you could also allocate the memory dynamically. Example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE* file = fopen("file.txt", "rt");
if(file == NULL) {
perror("file.txt");
return 1;
}
int primNum;
int secNum;
if(fscanf(file, "%d %d", &primNum, &secNum) != 2) {
fprintf(stderr, "failed reading primNum and secNum\n");
return 1;
}
unsigned numberOfLines = 0;
// allocate space for one `int`
int* listOfNumers = malloc((numberOfLines + 1) * sizeof *listOfNumers);
// the above could just be:
// int* listOfNumers = malloc(sizeof *listOfNumers);
while(fscanf(file, "%d", listOfNumers + numberOfLines) == 1) {
++numberOfLines;
// increase the allocated space by the sizeof 1 int
int* np = realloc(listOfNumers, (numberOfLines + 1) * sizeof *np);
if(np == NULL) break; // if allocating more space failed, break out
listOfNumers = np; // save the new pointer
}
fclose(file);
puts("List of Numbers:");
for(unsigned i = 0; i < numberOfLines; ++i) {
printf("%d\n", listOfNumers[i]);
}
free(listOfNumers); // free the dynamically allocated space
}
There are a few ways to approach this; if you know the size of the first line, you should be able to use fseek to move the position of the file than use getline to get each line of the file:
int fseek(FILE *stream, long offset, int whence);
The whence parameter can be:
SEEK_SET : the Beginning
SEEK_CUR : the current position
SEEK_END : the End
The other option would to encapsulate the entire file read in a while loop:
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
int counter = 0;
while((linelen = getline(&line, &linecap, file)) != -1){
if counter == 0{
sscanf(line, "%d %d\n", &primNum, &secNum);
}else{
//Process your line
}
counter++; //This would give you your total line length
}

Struct fscanf in file C

In file I need to read some inputs:
this is an example:
8 15
[1,1] v=5 s=4#o
[4,2] v=1 s=9#x
typedef struct{
int red2;
int stupac2;
int visina;
int sirina;
char boja[10];
}Tunel;
FILE* fin = fopen("farbanje.txt", "r");
Tunel* tuneli = malloc(sizeof(Tunel)*50);
// if(fin!=0)
fscanf(fin,"%d %d", &r,&s);
printf("%d %d", r,s);
int p=0;
while (fscanf(fin, "[%d,%d]", &tuneli[p].red2, &tuneli[p].stupac2) == 2)
{
p++;
}
for(i=0;i<p;i++)
{
printf("[%d,%d]", tuneli[i].red2, tuneli[i].stupac2);
}
Problem is that it wont read me properly inputs from here: [1,1] v=5 s=4#o
Last line where i use printf shows some random numbers.
Agree it is better to use fgets
But if you want to continue to use your current approach,
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int red2;
int stupac2;
int visina;
int sirina;
char boja[10];
}Tunel;
int main(){
int r, s, i;
FILE*fin=fopen("farbanje.txt", "r");
if(fin==NULL) {
printf("error reading file\n");
return 1;
}
Tunel *tuneli=(Tunel*)malloc(sizeof(Tunel)*50);
fscanf(fin,"%d %d\n", &r,&s);
printf("%d %d", r,s);
int p=0;
while (fscanf(fin, " [%d,%d]%*[^\n]", &tuneli[p].red2, &tuneli[p].stupac2) == 2)
{
p++;
}
fclose(fin);
for(i=0;i<p;i++)
{
printf("[%d,%d]", tuneli[i].red2, tuneli[i].stupac2);
}
}
Last line where i use printf shows some random numbers....
The random numbers you see are because the buffers to print were not properly populated yet.
This example shows how to read the file, using fgets() to read a line buffer, then use sscanf() to parse the first two values from the lines. (read in-code comments for a few other tips.)
int main(void)//minimum signature for main includes 'void'
{
int r = 0;
int s = 0;
char line[80] = {0};//{initializer for arrays}
int p = 0;
Tunel *tuneli = malloc(sizeof(*tuneli)*50);
if(tuneli)//always test return of malloc before using it
{
FILE *fin = fopen(".\\farbanje.txt", "r");
if(fin)//always test return of fopen before using it
{
fgets(line, sizeof(line), fin);
sscanf(line, "%d %d", &r, &s);
while(fgets(line, sizeof(line), fin))
{
sscanf(line, " [%d,%d]", &tuneli[p].red2, &tuneli[p].stupac2);
//note space ^ here to read only visible characters
printf("[%d,%d]\n", tuneli[p].red2, tuneli[p].stupac2);//content is now populated corretly
p++;
}
fclose(fin);//close when finished
}
free(tuneli);//free when done to prevent memory leaks
}
return 0;
}

2D array working inside the loop but not working outside the loop

I have coded a formula to read the txt file, store it in array(1D) and then reading the array to calculate the moving average(2D). Program ask the user to input two values (k1 & k2) and calculate the moving average for every value from k1 to k2 (basically to find out the best value)
Following is the code
#include<stdlib.h>
#define MAX_FILE_NAME 100
#define MAXCHAR 1000
int main()
{
FILE *fp;
int count = 0,k1=0,k2=0,k=0; // Line counter (result)
int buy[k2][count],sell[k2][count];
char filename[MAX_FILE_NAME];
char c; // To store a character read from file
// Get file name from user. The file should be
// either in current folder or complete path should be provided
printf("Enter file name or full path: ");
scanf("%s", filename);
printf("Enter the minimum rolling period for calculation : \n");
scanf("%d", &k1);
printf("Enter the maximum rolling period for calculation : \n");
scanf("%d", &k2);
// Open the file
fp = fopen(filename, "r");
// Check if file exists
if (fp == NULL)
{
printf("Could not open file %s", filename);
return 0;
}
// Extract characters from file and store in character c
for (c = getc(fp); c != EOF; c = getc(fp))
if (c == '\n') // Increment count if this character is newline
count = count + 1;
// Close the file
fclose(fp);
//printf("The file %s has %d lines\n", filename, count);
FILE *myFile;
myFile = fopen(filename, "r");
//read file into array
float numberArray[count];
int i;
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);
}
for (i = 0; i < count; i++){
fscanf(myFile, "%f,", &numberArray[i]);
}
fclose(myFile);
for (k=k1;k<=k2;k++)
{
float n;
float data[count],mag[k2][count];
double avg,sum;
for (i=0;i<k-1;i++)
{
mag[k][i-1]=0;
sum=sum+numberArray[i];
}
for(i=k-1;i<=count;i++)
{
mag[k][i-1]=avg;
sum=sum+numberArray[i]-numberArray[i-k];
avg = sum/k;
}
// for(i=0;i<=count;i++)
// {
// printf("MA[%d][%d] = %0.2lf ",k,i,mag[k][i]);
// if (i%3==0)
// printf("\n");
// }
}
for(k=k1;k<=k2;k++)
{
for(i=0;i<=count;i++)
printf("MA[%d][%d] = %0.2lf ",k,i,mag[k][i]);
}
}
}
Now when I am trying to print mag[k][i] values outside the for loop, it is showing error 'mag' undeclared. But when I am putting the print command inside the loop (comment out portion in the code), it works fine.
UPDATED CODE AFTER FOLLOWING COMMENTS (STILL NOT WORKING THOUGH)
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_FILE_NAME 100
#define MAXCHAR 1000
int main()
{
FILE *fp;
int count,k1,k2,k; // Line counter (result)
char filename[MAX_FILE_NAME];
char c; // To store a character read from file
// Get file name from user. The file should be
// either in current folder or complete path should be provided
printf("Enter file name or full path: ");
scanf("%s", filename);
printf("Enter the minimum rolling period for calculation : \n");
scanf("%d", &k1);
printf("Enter the maximum rolling period for calculation : \n");
scanf("%d", &k2);
// Open the file
fp = fopen(filename, "r");
// Check if file exists
if (fp == NULL)
{
printf("Could not open file %s", filename);
return 0;
}
// Extract characters from file and store in character c
for (c = getc(fp); c != EOF; c = getc(fp))
if (c == '\n') // Increment count if this character is newline
count = count + 1;
// Close the file
fclose(fp);
//printf("The file %s has %d lines\n", filename, count);
/****************
File opening and reading section
*****************************************************/
FILE *myFile;
myFile = fopen(filename, "r");
//read file into array
float numberArray[count];
int i;
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);
}
for (i = 0; i < count; i++){
fscanf(myFile, "%f,", &numberArray[i] );
}
fclose(myFile);
/***********************************************
Calculation of Moving Average and storing it in array
******************************************/
int buy[k2][count],sell[k2][count];
float mag[k2][count];
for (k=k1;k<=k2;k++)
{
float data[count];
double avg,sum;
for (i=1;i<k;i++)
{
mag[k][i-1]=0;
sum=sum+numberArray[i];
}
for (i=k-1;i<=count;i++)
{
mag[k][i-1]=avg;
sum=sum+numberArray[i]-numberArray[i-k];
avg = sum/k;
}
// for(i=0;i<=count;i++)
// {
// printf("MA[%d][%d] = %0.2lf ",k,i,mag[k][i]);
// if (i%3==0)
// printf("\n");
// }
}
for (k=k1;k<=k2;k++)
{
for (i=0;i<=count;i++)
{
printf("MA[%d][%d] = %0.2lf ",k,i,mag[k][i]);
}
}
}
The problem boils down to this: the scope of mag is limited to the inside of the for loop:
for (k = k1; k <= k2; k++)
{
...
int mag[k2][count];
...
}
// mag is out of scope here
// therefore following line won't compile:
printf("%d", mag[0][0]);
You need to declare mag outside the for loop for example like this:
int mag[k2][count];
for (k = k1; k <= k2; k++)
{
...
}
printf("%d", mag[0][0]);
...
Beware: there are other problems within your code, mentioned in the comments.

Reading and writing files in c

i wanna know why my program can't input the numbers of my .txt file them into my array. It reads them but i can't manage to input them into an array for later use.
Can anybody help me to understand better the management of reading and writing files in c, please i'm new at this topic, i know i'm supposed to use int instead of chars since my .txt file contains only numbers. But with the functions such as fgets is for chars only i think.
#include <stdio.h>
int main()
{
FILE* file;
char name[10] = "100.txt";
char line[10];
int n;
char i[5];
file = fopen(name, "rt");
if (file == NULL)
{
printf("There is no such file!\n");
return 0;
}
for (n=0; n < 100; n++){
fgets(line, 5, file);
//puts(line);
i[n]=line;
puts(i[n]);
}
fclose(file);
return 0;
}
if you switch to fscanf you can use int instead of char, and given that you are parsing a text file containing numbers it makes more sense. Assuming your 100.txt has 100 number separated by a whitespace this should work:
int main(int argc, char* argv[])
{
FILE* file;
char name[10] = "100.txt";
char line[10];
int n;
int numberArray[100];
file = fopen(name, "rt");
if (file == NULL)
{
printf("There is no such file!\n");
return 0;
}
for (n=0; n < 100; n++){
fscanf(file, "%d", &numberArray[n]);
}
fclose(file);
return 0;
}
Here is the link for an explanation of fscanf.
EDIT:
There is another, and more elegant solution, to use fscanf:
while (fscanf(file,"%d",&numberArray[n++]) == 1);
in that way you loop through your text file as long as there are numbers (i.e. until EOF). Be careful as the program could crash if the count of numbers in the text file is greater than the space allocated for the array.
For writing back to a file:
FILE* fp = fopen( "out_file.txt", "w" ); // Open file for writing
int arrNumSize = sizeof(numberArray) / sizeof(int);
for (int i = 0; i < arrNumSize; i++)
{
fprintf(fp, "%d", numberArray[i] );
}
fclose(fp);

Read a file containing an array of long in C

I am trying to get the data from an array of longs that I have just created but I got different data.
please see code below :
#include <string.h>
#include "readfile.h"
int main()
{
long wr_data [6] ;
wr_data[0] = 11;
wr_data[1] = 1100;
wr_data[2] = 1122323;
wr_data[3] = 11333;
wr_data[4] = 11434243;
wr_data[5] = 1166587;
writeFile(wr_data);
readFile();
return(0);
}
int readFile()
{
FILE *file;
long * data
printf("Error Reading File\n");;
/* Open file for both reading and writing */
file = fopen(fileName, "r");
if (file == NULL)
{
printf("Error Reading File\n");
return -1;
}
for (int i = 0; i < 5; i++)
{
fscanf(file, "%ld", &data[i] );
printf("data[%d]: %ld \n",i, data[i]);
}
fclose(file);
return 0;
}
int writeFile(long * data)
{
FILE *fp;
if (data != NULL)
{
if ((fp = fopen(fileName,"w")) == NULL)
return -1;
if (*data !=0 )
fwrite(data,sizeof(long),6,fp);
printf("Write data\n");
fclose(fp);
}
return 0;
}
the result I get is as follows :
Write data
data[0]: 140526045102081
data[1]: 47
data[2]: 197764
data[3]: 140526045102080
data[4]: 4096
I want to preserve the write function as it is as it comes from an existing code. I tried also the function fread but without success
fread(data, sizeof(long ), 6, file);
Thanks in advance for help.
It's working here. I made the following changes to your code:
//needed for malloc
#include <stdio.h>
//needed for output
#include <stdlib.h>
...
char *fileName = "so";
...
//allocate memory to store the values
long *data = (long *)malloc(sizeof(long)*6);
...
//read the stored longs
fread(data, sizeof(long ), 6, file);
int i;
for(i=0; i<6; i++)
printf("%ld\n", data[i]);
what do you think?
edit:
Well the main change was the memory allocation. When you want to store values of any kind, your program needs to be granted by the operating system a memory zone to store those values.
In this case we had two options, either create a staticly allocated array with a fixed size, or allocate the needed memory in a dynamic fashion with the malloc function or equivalent.
Don't forget, if you want to store something, first make sure you have a place for it to be stored (i.e. allocated memory). If you don't you will most likely get an error "Segmentation Fault" aka "SIGSEGV" which means that you tried to access memory that didn't belong to you.
Also, the "fscanf(file, "%ld", &data[i] );" will read "file" as text and will try to parse floats out of that same text. Since you're storing the longs as longs and not as text, this will not work, since you're writing and reading different things.
You are writing the binary content of the array to the file and afterwards try to interpret this as a long value which can obviously not work. If you want to store the numbers as text you must convert them to text before writing or print them to file by using the fprintf(FILE *, const char *, ...) function.
It is working as expected using the following code using a text file (you might want to change the filename). Otherwise you could just fwrite and fread the whole content, depending on your needs.
#include <stdio.h>
const char *filename = "yourfile";
int readFile()
{
FILE *file;
long data[6];
int i;
printf("Error Reading File\n");;
/* Open file for both reading and writing */
file = fopen(filename, "r");
if (file == NULL)
{
printf("Error Reading File\n");
return -1;
}
for (i = 0; i < 6; i++)
{
fscanf(file, "%ld", &data[i] );
printf("data[%d]: %ld \n",i, data[i]);
}
fclose(file);
return 0;
}
int writeFile(long * data)
{
FILE *fp;
int i;
if (data != NULL)
{
if ((fp = fopen(filename,"w")) == NULL)
return -1;
if (*data !=0 )
{
for(i = 0; i != 6; ++i)
fprintf(fp, "%ld ", data[i]);
}
printf("Write data\n");
fclose(fp);
}
return 0;
}
int main()
{
long wr_data [6] ;
wr_data[0] = 11;
wr_data[1] = 1100;
wr_data[2] = 1122323;
wr_data[3] = 11333;
wr_data[4] = 11434243;
wr_data[5] = 1166587;
writeFile(wr_data);
readFile();
return(0);
}

Resources