Parsing Integer and Float Values of a Text File with sscanf - c

I want to parse such a file with these fields into integer and float variables,I tried to do this using fscanf,strtok,sscanf. But none of them works!
Some lines of the file :
fed18 5.7 12.7 144997 8087 267345 100776
fedora18 24.9 25.3 253566 10501 126282 118157
fed18 5.9 12.7 145005 8094 267345 100785
fedora18 23.3 25.3 253576 10507 126282 118169
fed18 6.2 12.7 145013 8100 267345 100789
Running the following code returns wrong values! I don't know what's the problem as I search, everybody use such this code and it works properly for them!
while(fgets(str,512,fp)!= NULL)//read file line by line
{
char *tokenstring = str;
uint64_t netrx,nettx,vbd_rd,vbd_wr;
double cpu, mem;
char a[10],b[10],c[10],d[10],e[10],f[10],g[10];
sscanf(tokenstring, "%s ,%[^' '],%[^' '],%[^' '],%[^' '],%[^' '],%[^' ']",g, a, b, c, d, e, f);
cpu = atof(a);
mem = atof(b);
nettx = atoi(c);
netrx = atoi(d);
vbd_rd = atoi(e);
vbd_wr = atoi(f);
printf("%s %f %f %ld %ld %ld %ld\n",g,cpu,mem,netrx,nettx,vbd_rd,vbd_wr);
}
fclose(fp);
Here is the output:
fed18 38.000000 1.000000 0 0 0 0
fedora18 38.000000 1.000000 0 0 0 0
fed18 38.000000 1.000000 0 0 0 0
fedora18 38.000000 1.000000 0 0 0 0
fed18 38.000000 1.000000 0 0 0 0
I edited the original text file with a bash script and using awk ,....
The original lines were in this format:
fed18 --b--- 3616 6.3 1052640 12.7 1052672 12.7 3 1 125864 6023 1 0 254349 93082 7412662 4730752 0
fedora18 --b--- 4711 2.4 2101216 25.3 2101248 25.3 3 1 249151 8636 1 0 126083 113505 3306934 5992656 0
I selected some columns using a bash script.
maybe this caused the problem!
I commented the lines of using function atoi or atof but still output wrong values.

If you always expect a single space between arguments you can simply your format string and obviate the need for atoi, atof:
while(fgets(str,512,fp)!= NULL)//read file line by line
{
char *tokenstring = str;
uint64_t netrx,nettx,vbd_rd,vbd_wr;
char g[10];
double cpu, mem;
long int c, d, e, f;
sscanf(tokenstring, "%s %lf %lf %lu %lu %lu %lu", g, &cpu, &mem, &nettx, &netrx, &vbd_rd, &vbd_wr);
printf("%s %f %f %ld %ld %ld %ld\n",g,cpu,mem,netrx,nettx,vbd_rd,vbd_wr);
}
fclose(fp);

Your format string contains commas that don't exist in the input. That said, you should use %lf to parse floating point numbers into double and %lu to parse into uint64_t.
Note that you might run into trouble when the current locale isn't English because that influences which character C expects as a decimal point. Use setlocale(LC_NUMERIC, "C"); to fix that.

scanf is designed to parse numbers so there is no need to use atoi, so just use sscanf with proper parameters
int result = sscanf(tokenstring, "%s %lf %lf %lld %lld %lld %lld",g, &cpu, &mem, &netrx, &netrx, &vbd_rd, &vbd_wr);
assert( result == 7 ) ;

Related

How can fscanf(), in C, be used to read a .gro file?

I am trying to read the following gro file via a C code.
FJP in Pol Water in water t= 0.00000 step= 0
16
1FJP P 1 5.346 7.418 0.319
2FJP P 2 5.151 7.405 0.499
3FJP P 3 5.260 7.178 0.428
4FJP P 4 5.159 6.961 0.342
5FJP P 5 5.355 6.909 0.220
6FJP P 6 5.169 6.824 0.043
7FJP P 7 5.068 6.669 11.454
8FJP P 8 4.919 6.861 11.482
9FJP P 9 4.835 7.075 11.364
10FJP P 10 4.738 6.987 11.197
11FJP P 11 4.847 7.115 10.993
12FJP P 12 4.642 7.126 10.870
13FJP P 13 4.680 6.940 10.674
14FJP P 14 4.521 7.052 10.545
15FJP P 15 4.321 6.973 10.513
16FJP P 16 4.315 6.728 10.516
11.56681 11.56681 11.56681
My code is:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
char input_file[]="file.gro";
FILE *input;
char *myfile=malloc(sizeof(char)*80);
sprintf(myfile,"%s",input_file); //the .gro file being read in
input=fopen(myfile,"r");
double dummy1,dummy6,dummy7,dummy8,dummy9,dummy10,dummy11;
int dummy2,dummy3,dummy4,dummy5;
int lines=0;
while (fscanf(input,"FJP in Pol Water in water t= %lf step= %d",&dummy1,&dummy2)==2
||fscanf(input," %d\n",&dummy3)==1
||fscanf(input," %dFJP P %d %lf %lf %lf\n",
&dummy4,&dummy5,&dummy6,&dummy7,&dummy8)==5
||fscanf(input," %lf %lf %lf\n",&dummy9,&dummy10,&dummy11)==3)
{
printf("%lf %d\n",dummy1,dummy2);
printf("%d\n",dummy3);
printf("%d %d\n",dummy4,dummy5);
printf("%lf %lf %lf\n",dummy6,dummy7,dummy8);
printf("%lf %lf %lf\n",dummy9,dummy10,dummy11);
lines=lines+1;
}
printf("lines=%d\n",lines);
fclose(input);
}
The problem is the values printed by the various dummy variables do not match what is in the file. Also, the number of lines being read is 3 as opposed to 19, which matches the file. I am not certain what is incorrect about my fscanf() statements to read this file. Any help for this problem would be much appreciated.
Your main problem is that you are assuming scanf is better than it is.
Scanf will read and parse as many arguments as it can, and then give up. It does not rewind to the start of the scanf. Also it treats spaces and newlines (and tabs) as simply "skip all whitespace"
So the line printf("%d\n",dummy3) will try to parse the main lines, eg 1FJP
It will read the digit 1 OK into dummy3, but then get stuck because P != a whitespace.
All the other rules will then get stuck, because none of them expect a P or any string first.
If you want to do it this way, you will just have to apply the scanf statements more intelligently as and when they are expected.
The problem is that you try to read and match the header repeatedly, before each line read (in the while loop.) you should read the head once, then read the lines. You also only need to skip any given piece of whitespace once. So you end up with code like:
if (fscanf(input,"FJP in Pol Water in water t=%lf step=%d%d", &dummy1, &dummy2, &dummy3) != 3) {
fprintf(stderr, "Invalid header\n");
exit(1); }
while (fscanf(input,"%dFJP P%d%lf%lf%lf", &dummy4, &dummy5, &dummy6, &dummy7, &dummy8) == 5) {
... read a line of the table

What is the error in following MPI program to calculate area under curve by rectangles' area summation approach

I am calculating the value of pi(3.14) by finding area under the curve 4/1+(x*x) from limits 0 to 1. Following is MPI program in C for doing so.
However, when there is one process, it gives correct value. If I give more than one process then only process having rank 0 gives some value while other processes give 0.0 as their locally computed value
What error is there in the following code ?
#include<mpi.h>
#include<math.h>
#include<stdio.h>
#define MAX_NAME 80
int main(int argc,char *argv[])
{
MPI_INIT(&argc,&argv);
int rank,nprocs,len;
double i=0.0;
double n=1000000000.0;
double PI25DT =3.141592653589793238462643;
double mypi,pi,step,sum,x;
char name[MAX_NAME];
double start_time,end_time,computation_time;
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Get_processor_name(name,&len);
start_time=MPI_Wtime();
sum=0.0;
step=1.0/(double)n;
x=0.0;
x=(double)rank*(n/nprocs);
x=x+step;
double temp=x;
for(i=temp;i<(temp+(n/nprocs));i=i+1.0)
{
sum+=step*(4.0/(1.0+(double)(x*x)));
x=x+step;
}
mypi=sum;
printf("\nProcessor: %d Name: %s Sum: %.16f \n",rank,name,mypi);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Reduce(&mypi,&pi,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
if(rank==0)
{
printf("\nValue of Pi is %.16f approximately .Error is %.16f \n",pi,fabs(pi-PI25DT));
end_time=MPI_Wtime();
computation_time=end_time-start_time;
printf("\nComputation time is: %f seconds.\n",computation_time);
}
MPI_Finalize();
}
Output of above code for one process and more than one process is as:
OUTPUT
The entire logic in your code seems flawed - you have confused integers and doubles in your "for" loop which means the loop limits are all wrong.
The easiest way to debug simple programs is just to print to the screen - I'm eternally surprised by how reticent people are to just get their program to tell them what it's actually doing.
If I set n=5.0 and change the loop to:
x=x+step;
printf("rank %d has x = %lf\n", rank, x);
then on 2 processes I get:
rank 0 has x = 0.400000
rank 0 has x = 0.600000
rank 0 has x = 0.800000
Processor: 0 Name: starless Sum: 2.0471212357622095
Value of Pi is 2.3040395511642187 approximately .Error is 0.8375531024255745
Computation time is: 0.000067 seconds.
rank 1 has x = 2.900000
rank 1 has x = 3.100000
rank 1 has x = 3.300000
Processor: 1 Name: starless Sum: 0.2569183154020093
showing the loop limits are wrong.
I don't think they're even correct on a single process:
rank 0 has x = 0.400000
rank 0 has x = 0.600000
rank 0 has x = 0.800000
rank 0 has x = 1.000000
rank 0 has x = 1.200000
Surely the integral is between 0.0 and 1.0?
Regards,
David

Q: About reading data files using fscanf()

Am using Turbo C in a DOS emulator (Dosbox). In the following lines, I am trying to read integer and float data but only get the first (int) field. Have found much Q & A on the subject of reading files using fscanf() and, specifically, with space-delimited data but relevant info was scant or missing (mostly from the questions). Here is code demonstrating the problem:
#include <stdio.h>
int index;
float rtime, volts;
char infilename[10];
int *pti;
float *ptx;
float *pty;
FILE *infp;
void main(void)
{
infp = fopen("data1", "r");
pti = &index;
ptx = &rtime;
pty = &volts;
fscanf(infp, "%d %6.3f %6.3f", &index, &rtime, &volts);
printf("%3d %6.3f %6.3f\n", index, rtime, volts);
}
Here is the first line from the data file:
37 261.100 0.996
printf gives the following output:
37 0.000 0.000
Any obvious goofs? thx
The format %6.3f is incorrect for scanf(). You probably want %f, or possibly %7f. You cannot specify the number of decimals in a scanf() format.

How to round float numbers in text in C?

So I have this text
today average human lifespan in Western countries is approaching and exceeding 80 years.
1 Japan 82.6 123 19
2 Hong Kong 82.2 234 411
3 Iceland 81.8 345 26
4 Switzerland 81.7 456 7
5 Australia 81.2 567 500
...
80 Lithuania 73.0 800 2
...
194 Swaziland 39.6 142 212
195 133714 18.0 133 998
196 100110011 10.0 667 87351
I need to round the float numbers in this text to whole numbers. I've searched a lot of forums but I cannot seem to find what I need.
This text is given in a .txt file. My task: "Round real number(that have decimals) to whole numbers. The corrected text should be in a new .txt" That's it.
scanf and sscanf are your best friend to extract anything of a string.
floor is use full to suppress decimal on a float. Then can be used to round it (to use it include math.h)...
The format string describes the expected format.The function return the number of parameters found.
Sample:
Initialization
int id = -1;
char country[160]; /* /!\ Warning country name length shall be fewer than 160 */
/* Scanf don't care of this array parameter length. If it is too short */
/* It will erase following memory... */
/* That is why scanf are often disparaging */
float percent = 0.0;
char a_number_as_string[10];
int other_number = -1;
char* Switzerland = "4 Switzerland 81.7654321 456 7";
effectif code
int ret = sscanf(Switzerland, "%d %s %f %s %d", &id, country,
&percent, a_number_as_string, &other_number);
if(ret == 5) {
printf("~~ id: %d\n\tcountry: %s\n\tpercent: %.2f\n\tand : "
"(%s, %d)\n", id, country, percent, a_number_as_string,
other_number);
/////// ROUND
printf("*** round");
printf("\twith printf %%.1f = %.1f\n", percent);
printf("\twith printf %%.2f = %.2f\n", percent);
printf("\twith printf %%.3f = %.3f\n", percent);
printf("\twith printf %%.4f = %.4f\n", percent);
printf("*** With floor (included in math.h)\n");
printf("\t1 decimal: %f\n", floor(percent*10)/10);
printf("\t2 decimal: %f\n", floor(percent*100)/100);
printf("\t3 decimal: %f\n", floor(percent*1000)/1000);
printf("\t4 decimal: %f\n", floor(percent*10000)/10000);
} else {
printf("--> ret = %d", ret);
}
output
~~ id: 4
country: Switzerland
percent: 81.70
and : (456, 7)
*** round
with printf %.1f = 81.8
with printf %.2f = 81.77
with printf %.3f = 81.765
with printf %.4f = 81.7654
*** With floor (included in math.h)
1 decimal: 81.700000
2 decimal: 81.760000
3 decimal: 81.765000
4 decimal: 81.765400
This function are describe in Unix, OSX, Unix terminal man pages:
man scanf
man sscanf
man floor
Or you can find it on several copies of this manages on the web for example
scanf
sscanf
floor
here is the program I have already tested it for a single line of input string:-
// LINK - http://stackoverflow.com/questions/40317323/how-to-extract-float-numbers-from-text-in-c#40317323
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main()
{
char s[100];
int i,j;
double sum=0.0,frac=0.0;
gets(s); // delimited by '\n' and not by ' '
for( i=0;s[i]!='\0';i++) // for finding index value of decimal point(.)
{
if(s[i]=='.')
break;
}
for(;s[i]!=' ';i--); // for changing key index value to the index value of the first space character(' ') before the decimal point(.)
i++;
for(i;s[i]!='.';i++)
{
sum=sum*10+(s[i]-48); // For extracting integer part
}
i++;
for(i,j=1;s[i]!=' ';i++,j++)
{
frac=frac+(s[i]-48)/pow(10,j); // For extracting fractional part
}
printf("\n\n%lf",sum+frac); // final answer integer part+decimal part
return 0;
}
Explanation:-
okay so what I did is:-
Since scanf() is automatically delimited by space I used gets() which is delimited by new line;
Then we know that there will be a decimal point(.) for floating number in the string, so we find the index value(say key) of the decimal point in the array.
Once we have found the decimal point we know there will only be numbers between the decimal point and the space character after the country name so now we find the index value of that space(key).
Now from that key value we again first move to the decimal point(.) character index while calculating the integer part.Calculated using ASCII value i.e. ASCII value of character Zero(0) is 48 and character Nine(9) is 57 hence subtracting 48 from every character and extracting the value.
Again from the Decimal point(.) to the next space character in the string is part of the floating number and after decimal the numbers follow the weight 10^(-1),10^(-2),10^(-3)...and so on hence the temporary variable and the power() function.Thus we, successfully calculated the fractional part also.
Finally, I just added the Integer and the fractional parts within the printf().
Try, using printf() with all the variables in each of the for loops for better understanding, kinda like dry-run.
You can parse all the values from the string using regex in c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] input = {
"today average human lifespan in Western countries is approaching and exceeding 80 years.",
"1 Japan 82.6 123 19",
"2 Hong Kong 82.2 234 411",
"3 Iceland 81.8 345 26",
"4 Switzerland 81.7 456 7",
"5 Australia 81.2 567 500",
"80 Lithuania 73.0 800 2",
"194 Swaziland 39.6 142 212",
"195 133714 18.0 133 998",
"196 100110011 10.0 667 87351"
};
string pattern = #"(?'index'\d+)\s+(?'country'.*)\s+(?'float'[^ ]+)\s+(?'num1'\d+)\s+(?'num2'\d+)$";
for (int i = 1; i < input.Length; i++)
{
Match match = Regex.Match(input[i], pattern);
Console.WriteLine("index : '{0}', country : '{1}', float : '{2}', num1 : '{3}', num2 : '{4}'",
match.Groups["index"],
match.Groups["country"],
match.Groups["float"],
match.Groups["num1"],
match.Groups["num2"]
);
}
Console.ReadLine();
}
}
}

The output of ceil() and floor() in C language is odd

I am doing my homework to realize a C programe and during my work there is one step that I need to get the interger part of the double type numbers. So I choose ceil() or floor() in to realize this. But the output is unpredictable and far from expected.
The whole program is the following :
/*
************************************************************************
Includes
************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <gsl/gsl_rng.h>
#include <time.h>
#include <math.h>
/* Solvent Particle Propersities*/
typedef struct
{
double vx,vy,rx,ry ; /* velocity AND position */
double cell; /* index of grid */
}solvent_p;
/* Cell Propersities*/
typedef struct
{
double vcm_x,vcm_y ; /* center of mass velocity */
int number; /* number of solvent in the cell */
double roation_angle; /* roation_angle of the cell */
}cell_p;
/* periodic boundary condition judging and adjusting fuction PBC */
void PBC(solvent_p *sol)
{
double L = 20.0; // box size 20
if(sol->rx >20) sol->rx=sol->rx-L;
if(sol->rx < 0) sol->rx=sol->rx+L;
if(sol->ry >20) sol->ry=sol->ry-L;
if(sol->ry < 0) sol->ry=sol->ry+L;
}
int main(int argc, char **argv)
{
// Randome setup generates random numbers from GSL functions
const gsl_rng_type * T;
gsl_rng * r;
T = gsl_rng_default;
gsl_rng_default_seed = ((unsigned long)(time(NULL))); //设seed值为当前时间
r = gsl_rng_alloc (T);
solvent_p solvent[4000];
int i,j,k,index=0;
cell_p grid[400];
double alpha=90.0; //roation angle
/* Iniinitializing solvent
* All vx=0
* half vy = sqrt(3) and half vy=-sqrt(3) to make momentum zero and another requirement is the overall energy is 6000 equals energy of temperature=1 with 4000 solvent 3NkT/2 ,assuming mass of solvent = 1 ,which is all a test quantity
* rx and ry are random number generated by GSL library
* cell=20*(ry+rx) is an index of which cell the solvent is in
*/
for(i=0;i<=3999;i++)
{
solvent[i].vx=0.0;
if(i<=1999)
solvent[i].vy=sqrt(3);
else
solvent[i].vy=-sqrt(3);
solvent[i].rx =20.0 * gsl_rng_uniform_pos(r);
solvent[i].ry =20.0 * gsl_rng_uniform_pos(r);
//printf("%f \t %f \n",solvent[i].rx,solvent[i].ry);
solvent[i].cell=20*(floor(solvent[i].ry))+floor(solvent[i].rx)+1;
}
// grid setting up
for (i=0;i<=399;i++)
{
grid[i].vcm_x=0;
grid[i].vcm_y=0;
grid[i].number=0;
grid[i].roation_angle=0.0;
}
/* Begining Simulation Work
*
* Fist process is preparing the system to equilibrium for 10000 processes
*
* the whole process involving two steps steaming and collision and the two steps are conducted one by one in our simulation
* time duration for steaming is 0.1 which is assigned for Molecular Dynamics and time duration for collision is ignored
*
*
*/
for(i=0;i<=9999;i++)
{
double temp;
double delta_t_MD=0.1; //time step
temp=gsl_rng_uniform_pos(r);
double rand_rx = (temp < 0.5) ? temp : ((-1) * temp ); // randomshift rx;
temp=gsl_rng_uniform_pos(r);
double rand_ry = (temp < 0.5) ? temp : ((-1) * temp ); // randomshift ry
//steaming
for(j=0;j<=3999;j++)
{
//printf("%d \n",j);
printf("1 :%d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
solvent[j].rx=solvent[j].rx+solvent[j].vx * delta_t_MD;
solvent[j].ry=solvent[j].ry+solvent[j].vy * delta_t_MD;
printf("2: %d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
//randomshift
solvent[j].rx=solvent[j].rx+rand_rx;
solvent[j].ry=solvent[j].ry+rand_ry;
printf("3: %d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
// periodic boundary condition
PBC(&solvent[j]);
printf("4: %d \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry);
solvent[j].cell=20*(ceil(solvent[j].ry)-1)+ceil(solvent[j].rx);
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[j].ry,ceil(solvent[j].rx),ceil(solvent[j].ry));
index = (int)(solvent[j].cell);
//printf("%d \t %d \t %f \t %f \t %f \n",j,index,solvent[j].cell,ceil(solvent[j].rx),ceil(solvent[j].ry));
if ((index>=0) &&(index<=400))
{
grid[index].vcm_x=grid[index].vcm_x+solvent[i].vx;
grid[index].vcm_y=grid[index].vcm_y+solvent[i].vy;
grid[index].number=grid[index].number+1;
}
}
// caculating vcm
for (k=0;k<=399;k++)
{
if (grid[k].number >= 1)
{
grid[k].vcm_x=grid[k].vcm_x/grid[k].number;
grid[k].vcm_y=grid[k].vcm_y/grid[k].number;
}
double temp;
temp=gsl_rng_uniform_pos(r);
grid[k].roation_angle = (temp < 0.5) ? alpha : ((-1) * alpha );
}
//collsion
}
gsl_rng_free (r); // free RNG
return 0;
}
Sorry it is some extent long so I did not put in first.And something did not finished but the program framework is set up.
my programe is like this:
printf("4: %d \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry);
solvent[j].cell=20*(floor(solvent[j].ry))+floor(solvent[j].rx)+1;
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry,floor(solvent[j].rx),floor(solvent[j].ry));
And although something as I wanted something more is wrong and below is I choose some parts of the output:
4: 3993 3.851240 17.047031
5: 3993 3.851240 17.047031 3.000000 9.000000
although floor(solvent[j].rx) is right but floor(solvent[j].ry) is totally wrong.
And the final result of my program is
Segmentation fault (core dumped)
------------------
(program exited with code: 139)
How to fix this one? Is there anything I use was wrong?
And to further test the problem I tried ceil() function in and the program and result is like this
program:
printf("4: %d \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry);
solvent[j].cell=20*(ceil(solvent[j].ry)-1)+ceil(solvent[j].rx);
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry,ceil(solvent[j].rx),ceil(solvent[j].ry));
result:
2: 3999 14.571205 2.837654
4: 3999 14.571205 2.837654
5: 3999 14.571205 2.837654 15.000000 15.000000
So use the nearest output as an example to illustrate my desire result is:
a= 14.571205, ceil(a)=15.00
b= 2.837654 , ceil(b)=3.00 not the 15.000 in the output
And the problem worsening is that when I just use a and b to test ceil() everything seems perfect:
program:
#include <stdio.h>
#include <math.h>
int main()
{
double a= 14.571205;
double b= 2.837654 ;
printf("%f \t %f \n",ceil(a),ceil(b));
return 0;
}
output:
15.000000 3.000000
I am using GCC in Linux Ubuntu.
==============================================================================
The problem has been solved.
The real fatal problem is here
if ((index>=0) &&(index<=400))
{
grid[index].vcm_x=grid[index].vcm_x+solvent[i].vx;
grid[index].vcm_y=grid[index].vcm_y+solvent[i].vy;
grid[index].number=grid[index].number+1;
}
}
Both solvent[i].vy and solvent[i].vx should be changed i for j.
Just as #Jon and #Blckknght #Eric Lippert have pointed out.
And I obvious get in the wrong trap and mislead #ouah and #Blckknght and In fact, the output sentences do have problem but they do not caused the prorame to crash only the out of boundary will do that.
Thank you ALL!
And I do like to share Eric Lippert 's comment which is powerful and insightful:
More generally, the problem you have is called "select isn't broken" by experienced programmers. That is, you have done something completely wrong, you cannot figure out what you did wrong, and so you conclude that a piece of basic, easy infrastructure written by experts and tested extensively is wrong. I assure you, floor and ceil do exactly what they are supposed to do. They are not wrong. The problem lies somewhere in your code, not in the standard library. – Eric Lippert
Your array is declared as:
solvent_p solvent[4000];
but you have this loop:
for(i=0;i<=9999;i++)
with this function call inside:
printf("1 :%d \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry);
which means you are accessing out-of-bounds array elements.
EDIT:
OP test case has been edited to fix the out-of-bound accesses.
My second suggestion is to check index value (which is used to index grid array) never exceeds the number of elements of grid array after this assignment: index = (int)(solvent[j].cell).
I'm pretty sure the issue is with the indexes you're using. In the statement in question:
printf("5: %d \t %f \t %f \t %f \t %f \n",j,solvent[j].rx,solvent[i].ry,floor(solvent[j].rx),floor(solvent[j].ry));
you are printing the ry value of solvent[i] but the floor of the ry value of solvent[j]. I suspect that you want to be using the same index in both places (though I'm not sure which index you want).

Resources