fscanf not able to read the values - c

I am trying to read a text file using fscanf.I am working in eclipse in OpenCV on ubuntu.
Here are some sample values in the text file
0 5 7 0.547619047619048 1 0.0274509803921569 1
0 6 8 0.541666666666667 1 0.0313725490196078 1
0 8 10 0.533333333333333 1 0.0392156862745098 1
But all fscanf reads is zeros in the array.Here is the part of the code that reads the values
long double testd[1000][6]
FILE* fid1=fopen("file","r");
while((fscanf(fid1,"%Lf",&b))==1)
{
printf("%Lf\n",b);
testsamplecount=testsamplecount+1;
}
for (i=0;i<testsamplecount/6;i++)
{
fscanf(fid1,"%Lf %Lf %Lf %Lf %Lf %Lf",
&testd[i][0],&testd[i][1],
&testd[i][2],&testd[i][3],
&testd[i][4],&testd[i][5]);
}

testd[i][0], etc, is an rvalue. What you need is &testd[i][0].

The first loop consumes the file. Try rewind(fid1); between the loops.
Edit: alternatively, as an option maybe a little more laborious but twice as performant, do a single loop, reading until there is no more data.

I think you don't move the file pointer to the start point of the file.
Use the library fseek(fp, 0, 0) or
Try close the file and then open again.

Related

How to read one line at a time from a data file and to perform calculations in it before moving to the next line in C Programming?

I'm a beginner at C programming and I would appreciate some help in order to understand the problem.
Alright so, I have a data file (input.dat) with data like this: (first line) 0 2 3 4 5; (second line) 1 2 3 5 4, (third line and so on...). I'm required to read the data one line at a time until the end of file and print it. This is what I have done so far:
int main(void)
{
float coeffs[5];
FILE *input; /* File pointer to the input file */
fopen_s(&input, "input.dat", "r"); /* Location of the input file */
int count = 0;
/* Loops to read data set*/
while (fscanf_s(input, "%f %f %f %f %f ", &coeffs[0], &coeffs[1], &coeffs[2], &coeffs[3], &coeffs[4]) != EOF)
{
printf("a=%.4f; b=%.4f; c=%.4f; d=%.4f; e=%.4f\n", coeffs[0], coeffs[1], coeffs[2], coeffs[3], coeffs[4]);
count++;
}
return 0;
}
This is showing all of the lines in the data file at once. But this is not what I want. I need to read one line at a time and perform some calculations and conditions for that one line first before I move to the next line. So how can I do that?
Next problem is, for the first line, I need to implement a loop from -10 to +10 with increment of 2 (to get 11 results in total). For example the program will read the first line, display it on the screen, then for the first value -10, the program will calculate and again display something . Then it will do the same for -8, then for -6 and so on until +10. After the 11 results are displayed, the program will then and ONLY then, move to the second line and so on. Hence for each line in the data file, the program will have 11 results. How can I use the loop function with increment of 2 to achieve these 11 results?
I would appreciate if anyone can provide me a simple layout of the structure of the codes which I've to write. NOTE: The formats are a bit different than other compilers as I must use Microsoft Visual Studio to do it.
Add your calculations to your while loop. You are reading one line at a time anyway.
If you want to loop from -10 to 10 with increments of 2, use a for loop.
for(count = -10; count <= 10; count = count + 2)
{
// Calculations
}

C: Write to a specific line in the text file without searching

Hello I have file with text:
14
5 4
45 854
14
4
47 5
I need to write a text to a specific line. For example to the line number 4 (Doesn't matter whether I will append the text or rewrite the whole line):
14
5 4
45 854
14 new_text
4
47 5
I have found function fseek(). But in the documentation is written
fseek(file pointer,offset, position);
"Offset specifies the number of positions (bytes) to be moved from the location specified bt the position."
But I do not know the number of bites. I only know the number of lines. How to do that? Thank you
You can't do that, (text) files are not line-addressable.
Also, you can't insert data in the middle of a file.
The best way is to "spool" to a new file, i.e. read the input line by line, and write that to a new file which is the output. You can then easily keep track of which line you're on, and do whatever you want.
I will assume that you are going to be doing this many times for a single file, as such you would be better indexing the position of each newline char, for example you could use a function like this:
long *LinePosFind(int FileDes)
{
long * LinePosArr = malloc(500 * sizeof(long));
char TmpChar;
long LinesRead = 0;
long CharsRead = 0;
while(1 == read(FileDes, &TmpChar, 1))
{
if (!(LinesRead % 500)
{
LinePosArr = realloc(LinePosArr, (LinesRead + 500) * sizeof(long));
}
if (TmpChar == '\n')
{
LinePosArr[LinesRead++] = CharsRead;
}
CharsRead++;
}
return LinePosArr;
}
Then you can save the index of all the newlines for repeated use.
After this you can use it like so:
long *LineIndex = LinePosFind(FileDes);
long FourthLine = LineIndex[3];
Note I have not checked this code, just written from my head so it may need fixes, also, you should add some error checking for the malloc and read and realloc if you are using the code in production.

reading a raw audio file as Matlab does in C

I have the following small script that I want to write in C :
`%% getting the spectgrum
clear, clc ;
fileName ='M0.raw'
[x,fs] = audioread(fileName);
[xPSD,f] = pwelch(x,hanning(8192),0,8192*4 ,fs);
plot(f,10*log10(abs(xPSD)));
xlim([0 22e3]);
absxPSD = abs(xPSD);
save('absXPSD.txt','absxPSD','-ascii');
save('xPSD.txt','xPSD','-ascii');
save('xValues.txt','x','-ascii');
save('frequency.txt','f','-ascii');`
without goning in details, I have a problem getting the correct result, when I checked I figured out that the data that I read is wrong here's sample that read the raw file to compare it with what Matalb reads :
#include <stdio.h>
#include <stdlib.h>
int main (){
FILE* inp =NULL;
FILE* oup =NULL;
double value =0;
inp = fopen("M0.raw","r");
oup = fopen("checks.txt","w+");
UPDATE
after LoPiTaL's answer I've tried to jump over the RIFF header which is 44Byte length0 using fseek
fseek (inp,352,SEEK_SET);// that didn't help getting the right result !!
if( inp == NULL || oup==NULL){
printf(" error at file opning \n");
return -1;
}
while (!(feof(inp))){
fread(&value,sizeof(double),1,inp);
printf(" %f \n ",value);
fprintf(oup,"%f\n",value);
}
fclose(inp);
fclose(oup);
return 0;
}
and the result that I get is :
-28083683309813134333858080554409220100578902032859386180468433149049781495379346137536863936326139303879846829175766826833343673613788446579155215033623707200818670767132304934425064429529496303287641688697019947073799877821581901737052884168025721481955133510652655692037990001524306465271815108431928360960.000000
0.000000
0.000000
0.000000
0.000000
0.000000
-20701636078248669570005757343846586744027511881225108933223144646890577802102653022204406730988428912367583701134782419138464527797567258583836429190479797597328678189654150340845........................................................................
and my aim is to get those value :
-1.0162354e-02
-9.3688965e-03
-7.5073242e-03
-1.9531250e-03
3.7231445e-03
1.3549805e-02
2.3223877e-02
3.2867432e-02
4.4830322e-02
5.5114746e-02
6.7291260e-02
7.7636719e-02
8.8562012e-02
9.5794678e-02
1.0055542e-01
1.0415649e-01
1.0351563e-01
1.0235596e-01
9.8785400e-02
9.1796875e-02
8.3648682e-02
7.1594238e-02
the audio file is mono an is 16bit resolution , any idea how can solve this ? thanks for any help
You must open the file in binary mode, for starters. Otherwise you get text mode, which can do translations of line endings, for instance. Not good with binary data.
Binary mode:
inp = fopen("M0.raw", "rb");
^
|
muy
importante
Sure, you cannot read an audio file as is and hope that the data is as you think it is.
Ignoring any coded audio file, which of course you have to decode prior to read it, lets focus in the RAW audio files:
RAW audio files usually are WAV files. WAV files have a .RIFF header at the beginning of the file, which obviously you would have to ignore before reading audio data.
http://en.wikipedia.org/wiki/Resource_Interchange_File_Format
After you have removed the RIFF header, then the data starts.
As you stated, the data is encoded as 16 bit resolution. 16 bit resolution means that 0x0000 is 0.0 and 0xFFFF is 1.0, and the size of the data is only two bytes!
So you have to read two bytes at a time (i.e. with a signed short) and then do the conversion to the range 0 to 1:
signed short ss;
double value;
FILE* inp =NULL;
inp = fopen("M0.raw","rb"); //As stated in other answer, use binary mode!
fseek (inp,44,SEEK_SET); // Only 44 bytes!!
//We already have discarded the header here....
while (fread(&ss, sizeof(signed short) ,1 , inp) == 1){
//Now we have to convert from signed short to double:
value=((double)ss)/(unsigned)0xFFFF;
//Print the results:
printf(" %f \n ",value);
fprintf(oup,"%f\n",value);
}
Of course, the function "audioread" from Matlab already does all of this for you, so you don't have to care about the encoding, as in your example, your particular data is in 16 bit, but if you use any other file, it could be 8, 16, 24 or 32, even could be differential or be encoded despite being a WAV file (see the RIFF header for more information).

read and gather variables in a text file

I asked this a while ago but was really vague and I also made some changes to my code.
I have a file that I call "stats.txt" which I open with: (using "C" btw)
fopen("stats.txt", r+)
During the first run of my program, I will ask the user to fill in the variables used to write to the file:
fprintf(fp, "STR: %i(%i)\n", STR, smod);
fprintf(fp, "DEX: %i(%i)\n", DEX, dmod);
etc...
the file looks like this after the programs first run, with all the numbers corresponding to a variable in the program:
Level 1 Gnome Wizard:
STR: 8(-1)
DEX: 14(2)
CON: 14(2)
INT: 13(1)
WIS: 13(1)
CHR: 12(1)
APP: 11(0)
Fort save: 0
Reflex save: 0
Will save: 3
when the program closes and runs for a second time, I have an "IF" statement checking for and displaying text within the "stats.txt" file:
if (fgets(buf, 1000, fp) == NULL)
{
printf("Please enter in your base stats (no modifiers):\n");
enter_stats();
printf("Please indicate your characters level:\n");
printf("I am a level ");
level = GetInt();
Race_check();
spec_check();
printf("------Base saving throws (no modifiers)------\n");
saving_throws();
}
else
{
printf("%s",buf);
}
The problem that I am having is the fact that the program reads the file, but does not transfer any variable values it seems here:
Level 1 Gnome Wizard:
-------------------------
STR: 0(-5)
DEX: 0(-5)
CON: 0(-5)
INT: 0(-5)
WIS: 0(-5)
CHR: 0(-5)
APP: 0(-5)
-----Saving Throws------
Fortitude: 0
Reflex: 0
Will: 0
Can anyone give me their suggestions on how to read the variables as well?
PLease and Thank you
Computers only understand numbers - they don't understand text. This means that you have to write code to convert the numbers (that represent individual characters) back into the values you want and store them somewhere.
For example, you might load the entire file into an "array of char", then search that "array of char" for the 4 numbers that represent STR:, then skip any whitespace (between the STR: and the 0(0)), then convert the character/s 0 into the value 0 and store it somewhere, then check for a ( character, then convert the characters -1 into the value -1 and store it somewhere, then check for the ) character and the newline character \n.
More likely is to arrange the code as a "for each line" loop, where the first characters of a line determine how to process the other characters. E.g. if the first character is - then ignore the line; else if the first 5 characters are level call a function that processes the remainder of the line (1 Gnome Wizard); else if the first few characters are STR:, DEX:, CON, etc call a function to get both numbers (and check for the right brackets, etc); else...
In addition to all this, you should have good error handling. As a rough guide, about half of the code should be checks and error messages (like if( buffer[i] != '(' ) { printf("ERROR: Expecting left bracket after number on line %u", lineNumber); return -1;}).

jumping to the a wanted line and overriding the first letter inside it in c

hello i am trying to write to a FILE in a wanted line number using c programming language
and for some unknown reasons it doesnt get written
this is my checking code:
int main()
{
int x;
int counter = 0;
char buffer[MAX];
FILE* fp = fopen("sale_day.txt","w");
fprintf(fp,"5 orange 11\n");
fprintf(fp,"4 pelephone 222\n");
fprintf(fp,"3 mirs 4000\n");
fprintf(fp,"2 cellcom 302\n");
fprintf(fp,"1 tmobile 500\n");
fclose(fp);
fp = fopen("sale_day.txt","r+");
while (counter < 2)
{// jumping two rows
fgets(buffer,MAX,fp);// i tried using fscanf which didnt help aswell
counter++;
}
fflush(fp); // i tried with and without still doesnt work
fputs("$",fp);
fflush(fp); // i tried with and without still doesnt work
fclose(fp);
}
i expect to get :
5 orange 11
4 pelephone 222
$ mirs 4000
2 cellcom 302
1 tmobile 500
for some reason it stays as the following in "sale_day.txt" file
5 orange 11
4 pelephone 222
3 mirs 4000
2 cellcom 302
1 tmobile 500
even tho when i debug it it shows a "$" instead of the 3 digit
thanks in advance for your help !
The code works just fine, also without the fflush-lines. After running the program, line 3 is changed as follows:
Before:
3 mirs 4000
After:
$ mirs 4000
I ran your code like it is, only with this on top:
#include <stdio.h>
#define MAX 255
What are you expecting? When I run your code, I get:
5 orange 11
4 pelephone 222
$ mirs 4000
2 cellcom 302
1 tmobile 500
This is exactly right given what you've coded: read two lines (leaving you positioned at the third line), and write a $ char.
Note that file write operations overwrite existing file data, or append new data to the end of a file. They don't insert data (which may have been the operation you're expecting).

Resources