How to assign a number (read from sd card) to a BigNumber variable!

Hello everyone! I am trying to read BigNumbers values with 20 digits after the decimal point from sd card.
I must take last value.
I obtain it but i don’t succeed to assign last value to a BigNumber variable to use it in other math operations.
Is there a solution?
I post my sketch:

#include <SPI.h>
#include <SD.h>
#include "BigNumber.h"
File myFile;

void printBignum (BigNumber n){
  char * s = n.toString ();
  Serial.println (s);
  free (s);
}  // end of printBignum

void setup(){
  Serial.begin(19200);
  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);
  digitalWrite(10, 1);
  
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
  }
  
  char c; 
  byte i; 
  char temp_arr[22];
  
  myFile = SD.open("valori.txt");
  if (myFile) {
    while (myFile.available()) {
                  
       while(c != -1) {
          c = myFile.read();
          i++;
          if(!myFile.available()) break;                   
          if (c == '\n') {
              temp_arr[i] = NULL;
              i=0;
          }
              
          temp_arr[i] = c;   
      }           
    }
    myFile.close();
  } 
  
  // -----------questa è la tua ultima riga ----------
  Serial.println(String(temp_arr)); //debug
  //-------------------------------------------------- 
  
 //---------------------------------------------------
 // In this step I try to assign temp_arr to a BigNumber variable but i don't succeed!!!!!!!!!!!!
 //--------------------------------------------------- 

BigNumber::begin (20);  // initialize library
BigNumber valore;
valore = BigNumber (temp_arr) ; 
Serial.print ( " valore: " );  
printBignum (valore);
 
}

void loop(){  
}

process the file line by line

you skip temp_arr[0] in your code causing errors if there is a 0 in it (probably is )

          if (c == '\n') {
              temp_arr[i] = NULL;
              i=0;
          }
              
          temp_arr[i] = c;

If you find a carriage return, append a NULL to the array. Then, set the index to 0. Then store the carriage return on position 0. Why?

Seems to me that there should be an else in there somewhere.

Hi matteo,

Apologies for my comment which got the big number thread locked…

Try this :- :wink:

#include <SPI.h>
#include <SD.h>
#include "BigNumber.h"
File myFile;

void setup() {
  Serial.begin(19200);
  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);
  digitalWrite(10, 1);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }

  char temp_arr[22];
  temp_arr[22] = 0; // <=== NULL terminated

  myFile = SD.open("valori.txt");
  if (myFile) {
    do {
      myFile.readBytes(temp_arr, 22);
      Serial.println(temp_arr); // <===== List all variables as they are read from SD
      myFile.read(); myFile.read(); // <=== discard <CR><LF>
    } while (myFile.available());
  }
  myFile.close();

  // -----------questa è la tua ultima riga ----------
  //Serial.println(temp_arr); //debug
  //---------------------------------------------------
  // In this step I try to assign temp_arr to a BigNumber variable but i don't succeed!!!!!!!!!!!!
  //---------------------------------------------------
  // Well actually you would have if your char array was correctly formed!! ;)

  BigNumber::begin (20);  // initialize library
  BigNumber valore;
  valore = BigNumber (temp_arr) ;
  Serial.print ( " di grande valore!! : " );
  Serial.println(valore); // <======= This was implemented some time ago, if it doesn't work, get the latest BigNumber library.
  // printBignum (valore); // <===== obsolete
}

void loop() {
}

Initializing SD card…
0.00006012897746378622
0.00000789641873453215
0.00000468768435435468
0.00000468768435435468
0.00004879642543541864
0.00000468768435435468
0.00000898865313154677
di grande valore!! : 0.00000898865313154677

This will only work for EXACTLY 20 decimal places, and assuming you have line terminator, if doesn’t work properly, remove one of the myFile.read() commands.

Hope this helps.

Regards,

Graham

  char temp_arr[22];
  temp_arr[22] = 0; // <=== NULL terminated

No, that’s an error. The NULL goes in the 1st element in the array, not one beyond the end of the array!

      myFile.readBytes(temp_arr, 22);
      Serial.println(temp_arr); // <===== List all variables as they are read from SD

Serial.println() expects a NULL terminated array. You are not passing it a NULL terminated arry. The readBytes() method return the number of bytes read, so that you can properly NULL terminate the array. Discarding that value is a mistake.

    do {
      myFile.readBytes(temp_arr, 22);
      Serial.println(temp_arr); // <===== List all variables as they are read from SD
      myFile.read(); myFile.read(); // <=== discard <CR><LF>
    } while (myFile.available());

No. This whole thing should be a while statement, so you don’t read from an empty file.

mmmm, well I don't claim to be a genius, of your level, but passing snide remarks is not helpful when a beginner is obviously struggling.

The example code works.

There was no claim the file would ever be empty hence why the loop was constructed the way it was.

A char [22] array has 23 elements? 0 - 22 ??

The 0 in element 22 is the NULL terminator which is never overwritten and hence only defined once, thus correctly terminating the fixed length 22 character string which actually occupies elements 0-21.....

Regards,

Graham

A char [22] array has 23 elements? 0 - 22 ??

No, it doesn't. The number in the brackets is the number of elements in the array. The elements are numbered 0 to 21.

Ok, thankyou for that, I have learnt something useful today :D

matteo, you need to change your array definition to this apparently. char temp_arr[23];

Regards,

Graham

ghlawrence2000: passing snide remarks is not helpful when a beginner is obviously struggling.

One person's "snide comment" might be another person's forehead-smacking "OMG, how could I have been so stupid?" comment.

We can't always tell whether a user really is a struggling noob, or an old-hand crossing-over from another language or architecture. Sometimes, you've got to smoke 'em out.

ghlawrence2000: mmmm, well I don't claim to be a genius, of your level, but passing snide remarks is not helpful when a beginner is obviously struggling.

PaulS is just trying to help. He has a lot of patience, doing 50000+ posts, helping people out.

Saying that something you are doing is "an error" is pretty mild stuff.

I've been glancing at some other forums today whilst trying to get at the bottom of some compiler behaviour, and I can tell you that some of them are pretty savage.

ghlawrence2000 I try to use your code and i modified it in this way but i don’t obtain last value.

#include <SPI.h>
#include <SD.h>
#include "BigNumber.h"
File myFile;

void printBignum (BigNumber n){
  char * s = n.toString ();
  Serial.println (s);
  free (s);
}  // end of printBignum

void setup() {
  Serial.begin(19200);
  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);
  digitalWrite(10, 1);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }

  char temp_arr[23];
  temp_arr[23] = 0; // <=== NULL terminated

  myFile = SD.open("valori.txt");
  if (myFile) {
    do {
      myFile.readBytes(temp_arr, 23);
      Serial.println(temp_arr); // <===== List all variables as they are read from SD
      myFile.read(); // myFile.read();  <=== discard <CR><LF>
    } while (myFile.available());
  }
  myFile.close();

  // -----------questa è la tua ultima riga ----------
  //Serial.println(temp_arr); //debug
  //---------------------------------------------------
  // In this step I try to assign temp_arr to a BigNumber variable but i don't succeed!!!!!!!!!!!!
  //---------------------------------------------------
  // Well actually you would have if your char array was correctly formed!! ;)

  BigNumber::begin (20);  // initialize library
  BigNumber valore;
  valore = BigNumber (temp_arr) ;
  Serial.print ( " di grande valore!! : " );
  Serial.println(valore); // <======= This was implemented some time ago, if it doesn't work, get the latest BigNumber library.
  // printBignum (valore); // <===== obsolete
}

void loop() {
}

This is result:

Initializing SD card...
0.00000000000747245117

0.00000000001291986807

0.00000000010383718147

0.00000000011130963264

0.00000000014191679263

0.00000000028899704904

0.00000000029444446594

0.00000000033115661854

0.00000000033660403544

0.00000000000544741690

0.00000000000544741690

0.00000000007464978720

0.00000000008009720410

0.00000000000544741690

 di grande valore!! : 0

I get still 0…

char temp_arr[23];
  temp_arr[23] = 0; // <=== NULL terminated

?

http://www.gammon.com.au/forum/?id=12153#trap11

Code gives me exact values but I don’t succeed to assign last number to a variable.
Is there a problem in this step?

  BigNumber::begin (20);  // initialize library
  BigNumber valore;
  valore = BigNumber (temp_arr) ;
  Serial.print ( " di grande valore!! : " );
  Serial.println(valore); // <======= This was implemented some time ago, if it doesn't work, get the latest BigNumber library.
  // printBignum (valore); // <===== obsolete
0.00000000000747245117

0.00000000001291986807

0.00000000010383718147

0.00000000011130963264

Explain the blank lines.

[quote author=Nick Gammon link=topic=269913.msg1903361#msg1903361 date=1412153722]

0.00000000000747245117

0.00000000001291986807

0.00000000010383718147

0.00000000011130963264

Explain the blank lines. [/quote]

Sorry! there aren't blank lines. This is an error when I copy and paste.

This is result:

Initializing SD card...
0.00000000000747245117
0.00000000001291986807
0.00000000010383718147
0.00000000011130963264
0.00000000014191679263
0.00000000028899704904
0.00000000029444446594
0.00000000033115661854
0.00000000033660403544
0.00000000000544741690
0.00000000000544741690
0.00000000007464978720
0.00000000008009720410
0.00000000000544741690
 di grande valore!! : 0

What do you say to reply #11?

[quote author=Nick Gammon link=topic=269913.msg1903373#msg1903373 date=1412154364] What do you say to reply #11?

[/quote]

what are you saying?? I don't understand ...

me or matteo?

That would be my fault! I originally had 22 as both parameters, matteo has just perpetuated my mistake. I always thought the index was absolute, I didn’t realise it was total number of elements, oops, such that [22] gives elements 0-21, I thought was 0-22, so I hold my hand up to that. :blush:

@matteo I thought I had made it clear that only 1 line needed changing and yet you appear to have replaced all occurrences of 22 with 23?

  char temp_arr[23];
  temp_arr[22] = 0; // <=== NULL terminated

  myFile = SD.open("valori.txt");
  if (myFile) {
    do {
      myFile.readBytes(temp_arr, 22);
      Serial.println(temp_arr); // <===== List all variables as they are read from SD
      myFile.read(); // myFile.read();  <=== discard <CR><LF>
    } while (myFile.available());
  }
  myFile.close();

Regards,

Graham

From the original post:

  char c; 
  byte i; 
  char temp_arr[22];
  
  myFile = SD.open("valori.txt");
  if (myFile) {
    while (myFile.available()) {
                  
       while(c != -1) {
          c = myFile.read();
          i++;

Where is "i" initialised?

AWOL:
From the original post:

  char c; 

byte i;
  char temp_arr[22];
 
  myFile = SD.open(“valori.txt”);
  if (myFile) {
    while (myFile.available()) {
                 
      while(c != -1) {
          c = myFile.read();
          i++;



Where is "i" initialised?

For that matter, first time around, c is ambiguous also.