-1

I amm dealing with Arduino cpp and I have a problem to set a variable (in structure) with a value. The variable is:

struct cronStructure {
    unsigned long every;      // every
    ...
}
...
cronStructure cron[] = {...

and the assignemet is generated by this fragment:

     unsigned long ss;
     sscanf(workBuffer+1,"%u",&ss);   // workBuffer contains d5
     cron[iEvent].every = ss;
     events.listEvents(cron);
     sprintf(printfBuffer," changed to %d\n", ss);
     Serial.println(printfBuffer);    // this shows: changed to 5
     Serial.println(cron[iEvent].every);  // this shows: 3827367941

Thanks

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
Rossati
  • 79
  • 1
  • 5
  • 2
    What is the problem you are having? Note that you are using both `%u` and `%d` for the format specifiers, neither is correct, `unsigned long` should be `%ul` – Alan Birtles Apr 08 '20 at 13:28
  • There is nothing *obviously* wrong with the code snippet you've shown (other than the format errors pointed out by @AlanBirtles) , so perhaps the issue occurs elsewhere. We can't see whether or not `iEvent` has a valid value, and we don't know what `event.listEvents(cron)` does. – Adrian Mole Apr 08 '20 at 13:29
  • @AdrianMole Using the wrong format specifiers causes UB and more practically speaking, the result shown by OP is not that surprising. They are reading and writing to the same part of `ss` and then later assign and print the whole `ss` which partially has non-sense in it. – walnut Apr 08 '20 at 14:17
  • @walnut - Excellent point! (Actually, after I posted, I did some playing around with signed and unsigned integers of different sizes and deliberately wrong scanf formats, and came to a similar conclusion.) – Adrian Mole Apr 08 '20 at 14:18

1 Answers1

-2

Thanks to all. My be is a problem of Arduino simil cpp compiler, I changed the capture of values and now it works:

          int ss;
          sscanf(workBuffer+1,"%i",&ss);
          Serial.println(cron[iEvent].every);
          cron[iEvent].every = (unsigned long) ss;
          events.listEvents(cron);
          sprintf(printfBuffer," changed to %i\n", ss);
          Serial.println(printfBuffer);
          Serial.println(cron[iEvent].every);
Rossati
  • 79
  • 1
  • 5
  • It is not a problem of the compiler, it is a problem of your code. You were using the wrong specifiers in `sscanf` and `sprintf` as pointed out by @AlanBirtles. When you don't follow the language rules you should not be surprised that you get wrong behavior. Your are just observing a possible outcome of *undefined behavior*. Btw., the explicit cast `(unsigned long)` is unnecessary. – walnut Apr 08 '20 at 14:22
  • " My be is a problem of Arduino simil cpp compiler" -> no it isn't. – Bathsheba Apr 08 '20 at 14:42
  • I have little knowledge of c language, so why isn't correct my workaround posted? My input can be contained in an integer and when obtained it is moved into a long. – Rossati Apr 08 '20 at 14:52
  • @Rossati Your code in the answer is ok now, but your explanation in the answer is not. Your code changes are not a workaround and the original code's behavior wasn't a problem with the compiler. Your original code was simply wrong. Your are making it sound as if your original code was correct, but the compiler just had a bug, which is not the case. Using the wrong format specifier results in [*undefined behavior*](https://stackoverflow.com/questions/2397984) in C and C++. You must always use the correct specifier for the type that you pass, e.g. the specifier for `unsigned long` is `%ul`. – walnut Apr 08 '20 at 14:57
  • Thanks walnut but changing to %ul doesn't works, besides %ul is not accepted in sprintf. unsigned long ss; sscanf(workBuffer+1,"%ul",&ss); cron[iEvent].every = ss; events.listEvents(cron); sprintf(printfBuffer," changed to %ul\n", ss); – Rossati Apr 08 '20 at 15:17
  • @Rossati Sorry, I meant `%lu`, not `%ul`. – walnut Apr 08 '20 at 15:46