Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #76223 > unrolled thread

Please help -- cannot read double data from file into array

Started bydakupoto@gmail.com
First post2015-11-17 00:39 -0800
Last post2015-11-19 11:13 +0000
Articles 15 — 6 participants

Back to article view | Back to comp.lang.c


Contents

  Please help -- cannot read double data from file into array dakupoto@gmail.com - 2015-11-17 00:39 -0800
    Re: Please help -- cannot read double data from file into array Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-17 00:54 -0800
    Re: Please help -- cannot read double data from file into array gamo <gamo@telecable.es> - 2015-11-17 11:36 +0100
      Re: Please help -- cannot read double data from file into array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-17 11:04 +0000
    Re: Please help -- cannot read double data from file into array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-17 11:02 +0000
    Re: Please help -- cannot read double data from file into array James Kuyper <jameskuyper@verizon.net> - 2015-11-17 06:51 -0500
    Re: Please help -- cannot read double data from file into array BartC <bc@freeuk.com> - 2015-11-17 12:08 +0000
      Re: Please help -- cannot read double data from file into array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-17 13:28 +0000
        Re: Please help -- cannot read double data from file into array BartC <bc@freeuk.com> - 2015-11-17 14:20 +0000
          Re: Please help -- cannot read double data from file into array dakupoto@gmail.com - 2015-11-17 20:50 -0800
            Re: Please help -- cannot read double data from file into array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-18 11:22 +0000
              Re: Please help -- cannot read double data from file into array BartC <bc@freeuk.com> - 2015-11-18 12:15 +0000
              Re: Please help -- cannot read double data from file into array dakupoto@gmail.com - 2015-11-18 23:07 -0800
                Re: Please help -- cannot read double data from file into array Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-19 10:41 +0000
                Re: Please help -- cannot read double data from file into array BartC <bc@freeuk.com> - 2015-11-19 11:13 +0000

#76223 — Please help -- cannot read double data from file into array

Fromdakupoto@gmail.com
Date2015-11-17 00:39 -0800
SubjectPlease help -- cannot read double data from file into array
Message-ID<bb0cef7b-950a-4fcb-a7c9-2a8fbe558cd7@googlegroups.com>
Could some C kanguage guru please help ?
I am trying to read double data from a 
simple text file into an array. The data 
can be read in correctly, but I am unable 
use the values read into the array, later.

The input file looks like:
0       5.091259e-09    -2.16165e+01
1       5.213820e-09    -2.76803e+01
2       5.357648e-09    -2.74552e+01
3       5.524594e-09    -1.84046e+01
4       5.611980e-09    -1.15479e+01
5       5.693378e-09    -5.40278e+00
6       5.768690e-09    -1.01834e+00
7       5.847084e-09    1.373752e+00
8       5.910280e-09    1.400719e+00
9       5.978795e-09    -5.31898e-01
10      6.089210e-09    -7.05779e+00
11      6.204666e-09    -1.59755e+01
12      6.322522e-09    -2.39013e+01
13      6.456074e-09    -2.76082e+01
14      6.600659e-09    -2.36523e+01
15      6.719486e-09    -1.56844e+01
16      6.804431e-09    -8.88031e+00
17      6.883560e-09    -3.05696e+00
18      6.959700e-09    1.044230e+00
19      7.037793e-09    2.966563e+00
....
....

Each double value in a line is separated
by a tab(\t). The data is read in, line 
line as a character string, and then each 
string is parsed to red in the numerical 
values. The data is stored in a 2 dimensional
array:

const unsigned int NUMROWS = 262144;
const unsigned int PWROF2 = 18;
char data[64];
FILE *fPtr = NULL;
double indata[262144][2];

To open and read the file I use:
void readFile(FILE *fPtr, double a[][2])
{
  assert(fPtr != NULL);
  assert(a != NULL);

  bzero(&data[0], 64*sizeof(char));

  while(fgets(&data[0], 64, fPtr) != NULL)
  {
    parsestring(&data[0], a);
    bzero(&data[0], 64*sizeof(char));
  }

}

To parse each character string read in I use:
void parsestring(char *cp, double a[][2])
{

  char *cptr = NULL;
  double temp0 = 0;
  double temp1 = 0;
  unsigned int i = 0;
  unsigned int pos = 0;

  if(cp != NULL)
  {
    cptr = strtok(cp, "\t");
    while(((cptr = strtok(NULL, "\t")) != NULL) &&
          (i < NUMROWS))
    {
        switch(pos)
        {
          case 0:
           pos++;
         case 1:
           temp0 = strtod(cptr, NULL);
           a[i][0]=temp0;
           printf("%f\n", a[i][0]);
           pos++;
          break;
          case 2 :
           temp1 = strtod(cptr, NULL);
           a[i][1] = temp1;
           printf("%f\n",a[i][1]);
           pos++;
          break;
          default:
          break;
        }
       i++;
      }
    pos = 0;
  }
}

Please note that the print statements above 
correctly print out the double values read
in as:
,,,,,
,,,,,
0.0000049470
5.7103690000
0.0000049471
7.3173590000
0.0000049472
5.2198320000
0.0000049473
-2.0194100000
0.0000049474
-9.5860700000
0.0000049475
-17.3948000000
0.0000049476
-21.9167000000
0.0000049477
-20.4255000000
0.0000049479
-10.0376000000
0.0000049480
-2.7841500000
.....
.....

Now the problem starts. If I try to 
use the contents of the 2 dimensional array
in any subsequent calculation, I find that
each of the stored values are zero.

Could somoene please provide some hints
as to what might be going wrong. Thanks
in advance for your help.
 



[toc] | [next] | [standalone]


#76224

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-11-17 00:54 -0800
Message-ID<3a1411f7-2178-4477-aca4-7ef8cfaecacc@googlegroups.com>
In reply to#76223
On Tuesday, November 17, 2015 at 8:39:20 AM UTC, daku...@gmail.com wrote:
> Could some C kanguage guru please help ?
> 
>   while(fgets(&data[0], 64, fPtr) != NULL)
>   {
This is your mistake. Pass in &a[i], where i is a counter 
>     parsestring(&data[0], a);
>     bzero(&data[0], 64*sizeof(char));
>   }
> 
> }
> 

> Now the problem starts. If I try to 
> use the contents of the 2 dimensional array
> in any subsequent calculation, I find that
> each of the stored values are zero.
> 
Because a isn't being filled, only the top row of a.

[toc] | [prev] | [next] | [standalone]


#76229

Fromgamo <gamo@telecable.es>
Date2015-11-17 11:36 +0100
Message-ID<n2evvk$dke$1@speranza.aioe.org>
In reply to#76223
El 17/11/15 a las 09:39, dakupoto@gmail.com escribió:
> Could some C kanguage guru please help ?
> I am trying to read double data from a
> simple text file into an array. The data
> can be read in correctly, but I am unable
> use the values read into the array, later.
>
> The input file looks like:
> 0       5.091259e-09    -2.16165e+01
> 1       5.213820e-09    -2.76803e+01

I'm not a guru, I'm dumb.
Why don't you use fscanf?

-- 
http://gamo.eu.pn/
The generation of random numbers is too important to be left to chance

[toc] | [prev] | [next] | [standalone]


#76232

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-17 11:04 +0000
Message-ID<87y4dwzy2p.fsf@bsb.me.uk>
In reply to#76229
gamo <gamo@telecable.es> writes:

> El 17/11/15 a las 09:39, dakupoto@gmail.com escribió:
>> Could some C kanguage guru please help ?
>> I am trying to read double data from a
>> simple text file into an array. The data
>> can be read in correctly, but I am unable
>> use the values read into the array, later.
>>
>> The input file looks like:
>> 0       5.091259e-09    -2.16165e+01
>> 1       5.213820e-09    -2.76803e+01
>
> I'm not a guru, I'm dumb.
> Why don't you use fscanf?

I agree about using a scanf function, but with fscanf there is no easy
way to check the line-based format.  Reading a line and using sscanf
can do that very easily.

However, if checking the data format is not very important, then fscanf
will be even simpler.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76231

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-17 11:02 +0000
Message-ID<874mgk28jo.fsf@bsb.me.uk>
In reply to#76223
dakupoto@gmail.com writes:

> Could some C kanguage guru please help ?
> I am trying to read double data from a 
> simple text file into an array. The data 
> can be read in correctly, but I am unable 
> use the values read into the array, later.
>
> The input file looks like:
> 0       5.091259e-09    -2.16165e+01
> 1       5.213820e-09    -2.76803e+01
> 2       5.357648e-09    -2.74552e+01
> 3       5.524594e-09    -1.84046e+01
> 4       5.611980e-09    -1.15479e+01
> 5       5.693378e-09    -5.40278e+00
> 6       5.768690e-09    -1.01834e+00
> 7       5.847084e-09    1.373752e+00
> 8       5.910280e-09    1.400719e+00
> 9       5.978795e-09    -5.31898e-01
> 10      6.089210e-09    -7.05779e+00
> 11      6.204666e-09    -1.59755e+01
> 12      6.322522e-09    -2.39013e+01
> 13      6.456074e-09    -2.76082e+01
> 14      6.600659e-09    -2.36523e+01
> 15      6.719486e-09    -1.56844e+01
> 16      6.804431e-09    -8.88031e+00
> 17      6.883560e-09    -3.05696e+00
> 18      6.959700e-09    1.044230e+00
> 19      7.037793e-09    2.966563e+00
> ....
> ....
>
> Each double value in a line is separated
> by a tab(\t). The data is read in, line 
> line as a character string, and then each 
> string is parsed to red in the numerical 
> values. The data is stored in a 2 dimensional
> array:
>
> const unsigned int NUMROWS = 262144;
> const unsigned int PWROF2 = 18;
> char data[64];
> FILE *fPtr = NULL;
> double indata[262144][2];

In C you need to use #define or an enum constant for this sort of
number.  I imagine this code comes from C++ whose rule allow using const
ints for array sizes at file scope.  That's probably why you've ended up
repeating the number.

I'd limit the number of file-scope objects (globals in the vernacular)
to the very minimum.  Certainly the line buffer and the FILE pointer
should not really be here.

>
> To open and read the file I use:
> void readFile(FILE *fPtr, double a[][2])
> {
>   assert(fPtr != NULL);
>   assert(a != NULL);
>
>   bzero(&data[0], 64*sizeof(char));

bzero is a non-standard function.  Nothing wrong with that, but since C
has memset which does the same job, there is really no need to use
bzero.

sizeof (char) is 1 by definition, but you should probably just use the
line buffer size directly:

  memset(data, 0, sizeof data);

Finally, there's no need to zero the line buffer anyway!

>   while(fgets(&data[0], 64, fPtr) != NULL)

Again, I'd use the array size directly:

   while(fgets(data, sizeof data, fPtr) != NULL)

and I prefer data to &data[0] but that's very much a style detail.
   
>   {
>     parsestring(&data[0], a);
>     bzero(&data[0], 64*sizeof(char));
>   }
>
> }
>
> To parse each character string read in I use:
> void parsestring(char *cp, double a[][2])
> {

I find this function is too complex.  You could use sscanf instead like
this:

  int row;
  double d1, d2;
  if (sscanf(cp, "%d %lf %lf", &row, &d1, &d2) == 3) {
      a[row][0] = d1;
      a[row][1] = d2;
  }

You might add further checks such as ensuring that row is in range.
This raises the question of what to do when there is some error in the
data.  I suggest that parsestring return an int (a bool for modern C) to
indicate that all is well.  You can then write

  int n_pairs = 0;
  while(fgets(data, sizeof data, fPtr) != NULL &&
        parsestring(data, a))
           n_pairs += 1;
  if (!feof(fPtr))
      fprintf(stderr, "Error reading data near line %d.\n", n_pairs);

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76236

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-11-17 06:51 -0500
Message-ID<n2f481$ckt$1@dont-email.me>
In reply to#76223
On 11/17/2015 03:39 AM, dakupoto@gmail.com wrote:
> Could some C kanguage guru please help ?
> I am trying to read double data from a 
> simple text file into an array. The data 
> can be read in correctly, but I am unable 
> use the values read into the array, later.
> 
> The input file looks like:
> 0       5.091259e-09    -2.16165e+01
> 1       5.213820e-09    -2.76803e+01
> 2       5.357648e-09    -2.74552e+01
> 3       5.524594e-09    -1.84046e+01
> 4       5.611980e-09    -1.15479e+01
> 5       5.693378e-09    -5.40278e+00
> 6       5.768690e-09    -1.01834e+00
> 7       5.847084e-09    1.373752e+00
> 8       5.910280e-09    1.400719e+00
> 9       5.978795e-09    -5.31898e-01
> 10      6.089210e-09    -7.05779e+00
> 11      6.204666e-09    -1.59755e+01
> 12      6.322522e-09    -2.39013e+01
> 13      6.456074e-09    -2.76082e+01
> 14      6.600659e-09    -2.36523e+01
> 15      6.719486e-09    -1.56844e+01
> 16      6.804431e-09    -8.88031e+00
> 17      6.883560e-09    -3.05696e+00
> 18      6.959700e-09    1.044230e+00
> 19      7.037793e-09    2.966563e+00
> ....
> ....
> 
> Each double value in a line is separated
> by a tab(\t). The data is read in, line 
> line as a character string, and then each 
> string is parsed to red in the numerical 
> values. The data is stored in a 2 dimensional
> array:
> 
> const unsigned int NUMROWS = 262144;
> const unsigned int PWROF2 = 18;
> char data[64];
> FILE *fPtr = NULL;
> double indata[262144][2];
> 
> To open and read the file I use:
> void readFile(FILE *fPtr, double a[][2])
> {
>   assert(fPtr != NULL);
>   assert(a != NULL);
> 
>   bzero(&data[0], 64*sizeof(char));
> 
>   while(fgets(&data[0], 64, fPtr) != NULL)
>   {
>     parsestring(&data[0], a);
>     bzero(&data[0], 64*sizeof(char));
>   }
> 
> }
> 
> To parse each character string read in I use:
> void parsestring(char *cp, double a[][2])
> {
> 
>   char *cptr = NULL;
>   double temp0 = 0;
>   double temp1 = 0;
>   unsigned int i = 0;
>   unsigned int pos = 0;
> 
>   if(cp != NULL)
>   {
>     cptr = strtok(cp, "\t");
>     while(((cptr = strtok(NULL, "\t")) != NULL) &&
>           (i < NUMROWS))
>     {
>         switch(pos)
>         {
>           case 0:
>            pos++;
>          case 1:
>            temp0 = strtod(cptr, NULL);
>            a[i][0]=temp0;
>            printf("%f\n", a[i][0]);
>            pos++;
>           break;
>           case 2 :
>            temp1 = strtod(cptr, NULL);
>            a[i][1] = temp1;
>            printf("%f\n",a[i][1]);
>            pos++;
>           break;
>           default:
>           break;
>         }
>        i++;
>       }
>     pos = 0;
>   }
> }
> 
> Please note that the print statements above 
> correctly print out the double values read
> in as:
> ,,,,,
> ,,,,,
> 0.0000049470
> 5.7103690000
> 0.0000049471
> 7.3173590000
> 0.0000049472
> 5.2198320000
> 0.0000049473
> -2.0194100000
> 0.0000049474
> -9.5860700000
> 0.0000049475
> -17.3948000000
> 0.0000049476
> -21.9167000000
> 0.0000049477
> -20.4255000000
> 0.0000049479
> -10.0376000000
> 0.0000049480
> -2.7841500000
> .....
> .....
> 
> Now the problem starts. If I try to 
> use the contents of the 2 dimensional array
> in any subsequent calculation, I find that
> each of the stored values are zero.

The only two-dimension array I could find in your program is named
indata. Since it's a file scope array with no explicit initializer, it
is implicitly zero-initialized. The code you've shown us contains not a
single statement that would change the value of any element of that
array. Therefore, it seems reasonable that the array would contain only
zeroes.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#76237

FromBartC <bc@freeuk.com>
Date2015-11-17 12:08 +0000
Message-ID<n2f580$g5i$1@dont-email.me>
In reply to#76223
On 17/11/2015 08:39, dakupoto@gmail.com wrote:

> The input file looks like:
> 0       5.091259e-09    -2.16165e+01
> 1       5.213820e-09    -2.76803e+01
> 2       5.357648e-09    -2.74552e+01
> 3       5.524594e-09    -1.84046e+01


> Please note that the print statements above
> correctly print out the double values read
> in as:
> ,,,,,
> ,,,,,
> 0.0000049470
> 5.7103690000

(This doesn't correspond to your input data. Should it? And what are the 
commas about?)

> Now the problem starts. If I try to
> use the contents of the 2 dimensional array
> in any subsequent calculation, I find that
> each of the stored values are zero.
>
> Could somoene please provide some hints
> as to what might be going wrong. Thanks
> in advance for your help.

A few people are saying that you are not writing to the array properly 
within parsestring(). I can't see it myself. If I strip out all the 
irrelevant stuff, then this code that writes into the array the same way 
you do seems to give the expected results:

#include <stdio.h>

void parsestring(char *cp, double a[][2]);

#define NUMROWS 262144

FILE *fPtr = NULL;
double indata[NUMROWS][2];

void readFile(FILE *fPtr, double a[][2])
{    parsestring(&data[0], a);
}

void parsestring(char *cp, double a[][2])
{
	a[0][0]=10.0;
	a[0][1]=20.0;
	a[1][0]=110.0;
	a[1][1]=120.0;
	a[2][0]=210.0;
	a[2][1]=220.0;
	a[3][0]=310.0;
	a[3][1]=320.0;
}

int main(void){
int i;

readFile(0,indata);

for (i=0; i<4; ++i) {
	printf("%d %f %f\n",i,indata[i][0],indata[i][1]);
}

}


But aside from that, when I tried to run your program, I didn't get 
anything printed at all, not even the wrong results!

I don't understand your code however; what is strtok(NULL, "\t") 
supposed to do for example?

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#76240

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-17 13:28 +0000
Message-ID<87si44zre2.fsf@bsb.me.uk>
In reply to#76237
BartC <bc@freeuk.com> writes:

> On 17/11/2015 08:39, dakupoto@gmail.com wrote:
<snip>
>> Could somoene please provide some hints
>> as to what might be going wrong. Thanks
>> in advance for your help.
>
> A few people are saying that you are not writing to the array properly
> within parsestring(). I can't see it myself.

That was certainly a problem, though there may have been other issues.

The two suggested fixes that I've noticed so far are to pass the right
row of indata to parsestring (from Malcolm), and pass indata as is
currently done but to use the row number that is present in the input to
store the data in the right place (from me).

> If I strip out all the irrelevant stuff, then this code that writes
> into the array the same way you do seems to give the expected results:
>
> #include <stdio.h>
>
> void parsestring(char *cp, double a[][2]);
>
> #define NUMROWS 262144
>
> FILE *fPtr = NULL;
> double indata[NUMROWS][2];
>
> void readFile(FILE *fPtr, double a[][2])
> {    parsestring(&data[0], a);
> }
>
> void parsestring(char *cp, double a[][2])
> {
> 	a[0][0]=10.0;
> 	a[0][1]=20.0;
> 	a[1][0]=110.0;
> 	a[1][1]=120.0;
> 	a[2][0]=210.0;
> 	a[2][1]=220.0;
> 	a[3][0]=310.0;
> 	a[3][1]=320.0;
> }

To the OP: I think BartC is just checking that the parameters types are
correct here.  Don't that this sketch as the right way to do it since it
removes your line-by-line loop and could be seen as suggesting that all
the data should be read into a single string first!

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76241

FromBartC <bc@freeuk.com>
Date2015-11-17 14:20 +0000
Message-ID<n2fcvj$d6p$1@dont-email.me>
In reply to#76240
On 17/11/2015 13:28, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:

>> void parsestring(char *cp, double a[][2])
>> {
>> 	a[0][0]=10.0;
>> 	a[0][1]=20.0;
>> 	a[1][0]=110.0;
>> 	a[1][1]=120.0;
>> 	a[2][0]=210.0;
>> 	a[2][1]=220.0;
>> 	a[3][0]=310.0;
>> 	a[3][1]=320.0;
>> }
>
> To the OP: I think BartC is just checking that the parameters types are
> correct here.  Don't that this sketch as the right way to do it since it
> removes your line-by-line loop and could be seen as suggesting that all
> the data should be read into a single string first!

Yes, I got the idea that there was a problem with the way the array was 
passed.

But I couldn't make the OP's program work. And I couldn't make head or 
tail of what strtok() was supposed to do; even after reading the docs I 
couldn't make it work.

So I created an alternative parsestring(), which uses your idea of 
taking the row number from the input:

void parsestring(char *cp, double a[][2])
{
char cptr[100];
double temp = 0;
unsigned int row = 0;
unsigned int col = 0;

if(cp != NULL)
{
    nexttoken(&cp,cptr,sizeof(cptr));
    row = atol(cptr);
    if (row>=NUMROWS) return;

    while (nexttoken(&cp,cptr,sizeof(cptr)) && col<2) {
       temp = strtod(cptr, NULL);
       a[row][col++]=temp;
    }
}
}

This uses an alternative to strtok that I know works! It's here (these 
functions will need forward declarations, or rearranged to be in the 
correct order):

int nexttoken(char **ptr,char *dest,int destsize)
{
char *p;
int n;
char c;
     p=*ptr;
     while (c=*p,c==' ' || c=='\t') ++p;

     if (c==0)
     {
         *ptr=p;
         *dest=0;
         return 0;
     }
     n=0;
     do
     {
         if (n<destsize)
         {
             *dest=c;
             ++dest;
             ++n;
         }
         ++p;
         c=*p;
     } while (!(c==0 || c==' ' || c=='\t'));
     *ptr=p;
     *dest=0;
     return n;
}

(This only allows space and tab separators.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#76353

Fromdakupoto@gmail.com
Date2015-11-17 20:50 -0800
Message-ID<7d656fba-e6eb-4a4b-af10-bc2447874d8a@googlegroups.com>
In reply to#76241
On Tuesday, November 17, 2015 at 9:21:04 AM UTC-5, Bart wrote:
> On 17/11/2015 13:28, Ben Bacarisse wrote:
> > BartC <bc@freeuk.com> writes:
> 
> >> void parsestring(char *cp, double a[][2])
> >> {
> >> 	a[0][0]=10.0;
> >> 	a[0][1]=20.0;
> >> 	a[1][0]=110.0;
> >> 	a[1][1]=120.0;
> >> 	a[2][0]=210.0;
> >> 	a[2][1]=220.0;
> >> 	a[3][0]=310.0;
> >> 	a[3][1]=320.0;
> >> }
> >
> > To the OP: I think BartC is just checking that the parameters types are
> > correct here.  Don't that this sketch as the right way to do it since it
> > removes your line-by-line loop and could be seen as suggesting that all
> > the data should be read into a single string first!
> 
> Yes, I got the idea that there was a problem with the way the array was 
> passed.
> 
> But I couldn't make the OP's program work. And I couldn't make head or 
> tail of what strtok() was supposed to do; even after reading the docs I 
> couldn't make it work.
> 
> So I created an alternative parsestring(), which uses your idea of 
> taking the row number from the input:
> 
> void parsestring(char *cp, double a[][2])
> {
> char cptr[100];
> double temp = 0;
> unsigned int row = 0;
> unsigned int col = 0;
> 
> if(cp != NULL)
> {
>     nexttoken(&cp,cptr,sizeof(cptr));
>     row = atol(cptr);
>     if (row>=NUMROWS) return;
> 
>     while (nexttoken(&cp,cptr,sizeof(cptr)) && col<2) {
>        temp = strtod(cptr, NULL);
>        a[row][col++]=temp;
>     }
> }
> }
> 
> This uses an alternative to strtok that I know works! It's here (these 
> functions will need forward declarations, or rearranged to be in the 
> correct order):
> 
> int nexttoken(char **ptr,char *dest,int destsize)
> {
> char *p;
> int n;
> char c;
>      p=*ptr;
>      while (c=*p,c==' ' || c=='\t') ++p;
> 
>      if (c==0)
>      {
>          *ptr=p;
>          *dest=0;
>          return 0;
>      }
>      n=0;
>      do
>      {
>          if (n<destsize)
>          {
>              *dest=c;
>              ++dest;
>              ++n;
>          }
>          ++p;
>          c=*p;
>      } while (!(c==0 || c==' ' || c=='\t'));
>      *ptr=p;
>      *dest=0;
>      return n;
> }
> 
> (This only allows space and tab separators.)
> 
> -- 
> Bartc

Thanks to each of you for your sample code, hints
and suggestions. This solution however works like 
a charm.
From past experience, I know that the strtok function
is rather temperamental -- if it works fine, if not,
one has to improvise. I have created similar functions
in the past using the built-in C library functions
'isdigit', 'iscntrl' etc., 
The final output looks like:
0.0000000051    -21.616500
0.0000000052    -27.680300
0.0000000054    -27.455200
0.0000000055    -18.404600
0.0000000056    -11.547900
0.0000000057    -5.402780
0.0000000058    -1.018340
0.0000000058    1.373752
0.0000000059    1.400719
0.0000000060    -0.531898
0.0000000061    -7.057790
0.0000000062    -15.975500
0.0000000063    -23.901300
0.0000000065    -27.608200
0.0000000066    -23.652300
0.0000000067    -15.684400
0.0000000068    -8.880310
0.0000000069    -3.056960
0.0000000070    1.044230
"testout" 262144L, 5816000C                1,1           Top

Just as expected. Thank you very much once again.
 

[toc] | [prev] | [next] | [standalone]


#76385

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-18 11:22 +0000
Message-ID<87bnary2l6.fsf@bsb.me.uk>
In reply to#76353
dakupoto@gmail.com writes:
<snip>
> Thanks to each of you for your sample code, hints
> and suggestions. This solution however works like 
> a charm.

I don't want to sound churlish (OK, I do!), but by what criterion did
you choose a solution involving an extra function and about 32 lines of
code over one involving just a handful and a single standard library
function?

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76391

FromBartC <bc@freeuk.com>
Date2015-11-18 12:15 +0000
Message-ID<n2hq0t$s0n$1@dont-email.me>
In reply to#76385
On 18/11/2015 11:22, Ben Bacarisse wrote:
> dakupoto@gmail.com writes:
> <snip>
>> Thanks to each of you for your sample code, hints
>> and suggestions. This solution however works like
>> a charm.
>
> I don't want to sound churlish (OK, I do!), but by what criterion did
> you choose a solution involving an extra function and about 32 lines of
> code over one involving just a handful and a single standard library
> function?

You mean those five lines intended to replace the body of parsestring:

  void parsestring(char *cp, double a[][2])
  {
    int row;
    double d1, d2;
    if (sscanf(cp, "%d %lf %lf", &row, &d1, &d2) == 3) {
        a[row][0] = d1;
        a[row][1] = d2;
    }

I've just tried it and I think it's simpler too!

(Normally I keep well away from scanf and have only ever used sscanf to 
read a single item already isolated with a nexttoken-like function. And 
that's only used for floating point numbers. And I understand now that 
strtod could do that job.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#76491

Fromdakupoto@gmail.com
Date2015-11-18 23:07 -0800
Message-ID<dfcb5a88-12b4-4ec5-998d-465031e63b74@googlegroups.com>
In reply to#76385
On Wednesday, November 18, 2015 at 6:22:23 AM UTC-5, Ben Bacarisse wrote:
> dakupoto@gmail.com writes:
> <snip>
> > Thanks to each of you for your sample code, hints
> > and suggestions. This solution however works like 
> > a charm.
> 
> I don't want to sound churlish (OK, I do!), but by what criterion did
> you choose a solution involving an extra function and about 32 lines of
> code over one involving just a handful and a single standard library
> function?
> 
> <snip>
> -- 
> Ben.

I tried both of yours and BartC's suggested solutions, and his worked - I was just looking
for a working solution that would enable me
to proceed with my task of calculating the 
FFT of very large data sets -- e.g., 500000
pairs of time domain data.
I am not sure why your solution did not work,
but from past experience, I have noticed that 
at crunch time, somewhat brute force methods
work best.

[toc] | [prev] | [next] | [standalone]


#76503

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-19 10:41 +0000
Message-ID<87bnaquv8x.fsf@bsb.me.uk>
In reply to#76491
dakupoto@gmail.com writes:
<snip>
> I am not sure why your solution did not work,
> but from past experience, I have noticed that 
> at crunch time, somewhat brute force methods
> work best.

Maybe I had a typo -- I don't know -- but what I suggested was not
clever or subtle; it was definitely in the brute force category as well.
Anyway problem, solved.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76505

FromBartC <bc@freeuk.com>
Date2015-11-19 11:13 +0000
Message-ID<n2kap6$g9h$1@dont-email.me>
In reply to#76491
On 19/11/2015 07:07, dakupoto@gmail.com wrote:
> On Wednesday, November 18, 2015 at 6:22:23 AM UTC-5, Ben Bacarisse wrote:
>> dakupoto@gmail.com writes:
>> <snip>
>>> Thanks to each of you for your sample code, hints
>>> and suggestions. This solution however works like
>>> a charm.
>>
>> I don't want to sound churlish (OK, I do!), but by what criterion did
>> you choose a solution involving an extra function and about 32 lines of
>> code over one involving just a handful and a single standard library
>> function?

> I am not sure why your solution did not work,
> but from past experience, I have noticed that
> at crunch time, somewhat brute force methods
> work best.

I used the following program to test the method using sscanf() to read 
the three items on each line. It was tested with the 20-line input file 
you provided and seemed to work.

But I don't know how either method would work with malformed or missing 
lines. Both however benefit from making use of the row index from the 
input line, although this doesn't guard against missing or duplicate rows.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUMROWS 262144
const unsigned int PWROF2 = 18;
char data[64];
FILE *fPtr = NULL;
double indata[NUMROWS][2];

void parsestring(char *cp, double a[][2])
{
   int row;
   double d1, d2;
   if (sscanf(cp, "%d %lf %lf", &row, &d1, &d2) == 3) {
       a[row][0] = d1;
       a[row][1] = d2;
   }
}

void readFile(FILE *fPtr, double a[][2])
{
//  assert(fPtr != NULL);
//  assert(a != NULL);

   memset(&data[0], 0, 64*sizeof(char));

   while(fgets(&data[0], 64, fPtr) != NULL)
   {
     parsestring(&data[0], a);
     memset(&data[0], 0, 64*sizeof(char));
   }

}

int main(void){
int i;
FILE *f;

if ((f=fopen("input","r"))==NULL) {
    puts("Can't open input");
    exit(EXIT_FAILURE);
}

readFile(f,indata);

fclose(f);

for (i=0; i<20; ++i) {
	printf("%d %g %f\n",i,indata[i][0],indata[i][1]);
}
}

(Note the %g format above; without this, the small values of the first 
column of doubles in the input would be printed as 0.0)

-- 
Bartc

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web