Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Strings in C - help
11-05-2012, 07:19 PM, (This post was last modified: 11-05-2012, 07:22 PM by pingotg.)
#21
RE: Strings in C - help
(11-05-2012, 03:53 PM)KiloOne Wrote: Sorry, I am confused, I thought strlen() did not report the null as a character. So how would strlen(tmp) report more than 64 if I only put 64 in it?

Thanks,
Dale
Because you put 64 in and there are already bytes in there, whose values are essentially random (being whatever is left in there).

You do not want those random values to be used so you need to terminate the 64 you put in.

After all, you never set the other bytes to anything (such as nulls)....

You just have:
char tmp[66] = "";
which will set the first byte to a null and leave the rest untouched. tmp is an auto variable so it gets whatever is in the stack memory space. Could be anything at all!

John
Reply
11-05-2012, 08:33 PM, (This post was last modified: 11-05-2012, 08:34 PM by KiloOne.)
#22
RE: Strings in C - help
Wouldn't they only be untouched until I put 64 in there?

Is there a problem not using null after 64 if I only ever read 64?

Doesn't char tmp[66]=""; tell the operating system to reserve memory at some pointer to pointer+66 for whatever I put in there?

Sorry, I know I could research some of this but as long as I have your attention Wink

Thanks,
Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
11-05-2012, 08:53 PM,
#23
RE: Strings in C - help
Hi

I think this easy routine can solve the problem

Code:
CDCPrintAnyLength (char * Str)

{
int Len = strlen(Str);
int Ctn = 0;
char Buf;
do
  {
   if ( (Ctn + 64) < Len)
    {
     Buf = Str[Ctn+64];
     Str[Ctn+64] = 0;
     CDC.printf("%s",Str+Ctn);
     Str[Ctn+64] = Buf;
    }
   else
    CDC.printf("%s",Str+Ctn);
   Ctn += 64;
  }
while (Ctn < Len);
}

I have not tested it but I think can work without problems.


Bye Bye, Moreno
Reply
11-05-2012, 08:58 PM, (This post was last modified: 11-05-2012, 09:01 PM by pingotg.)
#24
RE: Strings in C - help
(11-05-2012, 08:33 PM)KiloOne Wrote: Wouldn't they only be untouched until I put 64 in there?

Is there a problem not using null after 64 if I only ever read 64?

Doesn't char tmp[66]=""; tell the operating system to reserve memory at some pointer to pointer+66 for whatever I put in there?

Sorry, I know I could research some of this but as long as I have your attention Wink

Thanks,
Dale
You'll overwrite the first 64. What about the rest? Never been initialised so assume they're random. Not likely to be null, but could be.

Yes, char tmp[66] = ""; does reserve 66 but you don't know what's in there. Best to assume it'll be the worst possible data, sooner or later.

There doesn't seem any good reason for using the
= "";
since it just sets the first byte to a null, leaving the rest untouched.

So, you put 64 into tmp, leave 2 bytes which could be anything. Worse, if neither is a null you will then run off the end into goodness knows where (well, the thing you call will run off the end, i.e. CDC.print or whatever).

Don't take this the wrong way but you REALLY need to learn the basics of C.

John
Reply
11-05-2012, 09:50 PM,
#25
RE: Strings in C - help
John, I would just like to learn enough at this point to get my job done and I am happy with the progress I have made. If my questions become too dumb please ignore them.

The Punguino project seems to want to attract beginners but I have had to dig pretty deep beyond the basics in many areas to get SPI, I2C and SD working. I did not expect to have issues with basic things that have come up in this thread, but thats life I guess.

I have now a copy of Kernighan and Ritchie and refer as needed.

I still don't know why I need to know what is in the bytes I don't use. As long as I have the room for the bytes I put there I thought I was OK.

I will test your routine Moreno and report back, I'm sure it will work.

Thanks,
Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
12-05-2012, 07:45 AM, (This post was last modified: 12-05-2012, 07:46 AM by moreno.)
#26
RE: Strings in C - help
Hi

Pinguino is a young project and is that what makes it exciting.

We have the possibility to help it to grow strong and healthy.
The difficulties we face and solve today, becomes part of the its growth.

Is fantastic become the uncle (for father is too late 8<))) ) of this project.


Bye Bye, Moreno
Reply
12-05-2012, 09:55 AM, (This post was last modified: 12-05-2012, 09:56 AM by pingotg.)
#27
RE: Strings in C - help
(11-05-2012, 09:50 PM)KiloOne Wrote: I still don't know why I need to know what is in the bytes I don't use. As long as I have the room for the bytes I put there I thought I was OK.
You'd be OK if the extra bytes were nulls. Remember there is no stored string length so strlen and the other routines have to go looking for a null to work out where the string ends.

When you put 64 non-null bytes into an uninitialised 66-byte buffer you have 2 bytes at the end whose value is unknown. They're not likely to be nulls (but could be).

So any str function you pass the buffer to will wander off the end of the 64 and likely keep going off the end of the 66 too.

Nothing checks buffer boundaries or array limits in C (there are variants of C which do but not in C itself).

If you're lucky it will find a null fairly soon, and maybe manipulating 65 or 66 or 67 or 68 or ... bytes won't cause mayhem. Generally it corrupts things / causes what C calls a segmentation fault or the like. Some CPUs are set up to at least handle that - under Linux you get a specific result (program aborted lol); Windows has changed the message but something about an illegal operation was one I think.

John
Reply
12-05-2012, 03:31 PM,
#28
RE: Strings in C - help
Thanks, but it looks like ever since I found a workaround for the issues I was having with strcat(), I have understood how to extract the bytes I want from an area set aside for a chr string.

In my case, after I put 64 bytes in a 67 byte location reserved for tmp I only use a function that specifically extracts 64 bytes and does not look for a nul.

It appears that my understanding, which was enough to make my code work, crossed some sort of convention (or defined semantics) such that I must be careful that I do not use a str function that looks for a nul when it is maybe an issue like that which I am trying to solve in the strcat() issue.

I don't think that having to remember this is any harder that having to remember, all the time (regardless of whether I have crossed a convention), not to assign to a char reserved location, more bytes than it has reserved.

I have to say, and this is a personal assessment only so lets not try to defend our views ad infinitum, that my experience with this C 'environment' makes me feel like I have gone back to the stone age based on my 30+ years of programming in basic and object oriented VB6.

And thanks John for drilling this string null issue so many times here as I am sure it will benefit anyone having string issues.

Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply
12-05-2012, 05:22 PM, (This post was last modified: 12-05-2012, 05:27 PM by pingotg.)
#29
RE: Strings in C - help
In the code you posted at post #12, you use
strncpy(tmp,CDCline,64);
and then
CDC.print(tmp,strlen(tmp));
which should fail, perhaps often perhaps not, because strlen is looking at tmp which has no null to terminate the string.

(I've not looked to see what CDC.print does with tmp or with a bad result for the length.)

You can use (a variant of) Basic instead of C. It will run (say) 50 or 100 times slower and use a huge amount more memory. Quite often that's OK.

For example, you might have used an Olimex DuinoMite (DM). (It costs more, but not a lot more.)

The points of C, really, are speed, size and the ability to control exactly what happens and when. With that extra control comes danger and pickiness (if I can put it like that).

For even greater speed, smaller size and more control you'd use assembler.

John
Reply
12-05-2012, 05:40 PM,
#30
RE: Strings in C - help
John,

So, my basic understanding was that when you put characters into a string, that the null was added without me being required to worry about it.

Sorry, from Arduino documentation:
Code:
Examples
All of the following are valid declarations for strings.

  char Str1[15];
  char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
  char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
  char Str4[ ] = "arduino";
  char Str5[8] = "arduino";
  char Str6[15] = "arduino";


Possibilities for declaring strings


Declare an array of chars without initializing it as in Str1
Declare an array of chars (with one extra char) and the compiler will add the required null character, as in Str2
Explicitly add the null character, Str3
Initialize with a string constant in quotation marks; the compiler will size the array to fit the string constant and a terminating null character, Str4
Initialize the array with an explicit size and string constant, Str5
Initialize the array, leaving extra space for a larger string, Str6

Null termination


Generally, strings are terminated with a null character (ASCII code 0). This allows functions (like Serial.print()) to tell where the end of a string is. Otherwise, they would continue reading subsequent bytes of memory that aren't actually part of the string.


This means that your string needs to have space for one more character than the text you want it to contain. That is why Str2 and Str5 need to be eight characters, even though "arduino" is only seven - the last position is automatically filled with a null character. Str4 will be automatically sized to eight characters, one for the extra null. In Str3, we've explicitly included the null character (written '\0') ourselves.

Are you saying I should add the null whenever I write characters to a string just to be safe?

Dale
PIC32-Pinguino-OTG Rev C and PIC32-PINGUINO-MICRO rev.B
Win XP SP3
r381 x.3 Big Grin
AND spi.c {} error fixed
AND sdmmc.c pin error fixed
AND diskio.c fixed, MICRO can't use the RTCC
AND analog.c fixed for MICRO
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)