If I send a string like "filename.wav" via the I2C library functions and then on the receiver I get one char at a time, what kind of variable should I be reading it into?
e.g.
char *myfile
or
char myfile[11]
???
Where I get confused is if I have a filename that is less 11 characters total and I am storing it in a char array of fixed length (like the myfile[11]). Would it be expected that most functions that are looking for a filename would read through the array only up to the part that has the file extension (e.g. ".wav") and not past this? Does a string that is sent like this Wire.send("teststring") automatically have an extra null character added to the end?
i.e. Would the receiver see 10 characters? or 11 characters? (teststring+'/0')
This leads to my next question:
Also the function to read in this string from the I2C bus would be like this?
int i = 0;
While (0 < Wire.available())
{
myfile[i] = Wire.receive();
}
Is that ok? or do I need to read one more character (the null added)
And so if there was a function declared like this:
Typically, "strings" in C are terminated with a null character, and it's your responsibility to make sure that it's there.
char *myfile = "filename.wav";
will actually generate a 12-byte "thing" in memory (8 bytes for the name, one for the dot, three for the type, and one for the terminating null.)
Typically, you'd do something like this:
char myfile[12];
void get_filename()
{
char c;
byte i;
memset(myfile, 0, sizeof(myfile)); // initialize to zeros
i = 0;
while (i < sizeof(myfile)) {
c = getc_w_wait();
if (c == '\r") {
break;
}
myfile[i++] = c;
}
}
(You know all those "buffer overflow bugs" you hear about making windows (and other sw) so insecure? That's what hapens when you make your filename array 12 bytes long, but don't check carefully enough that you only try to put 12 bytes of data into it. C will happily keep going, overwriting whatever other variables happen to be after C in memory...)
In your example you initialize the myfile array but where is the null character then? Does setting to "zero" mean they are full of null characters or full of the character/numer "0"?
When you are reading in each character you stop writing to the array once you receive the '\r'
so if the string you read in is less than I am assuming that the rest of the array is still filled with the null characters so whatever function that reads from the array should stop reading once it hits those?
Almost without exception which transmit strings, including Wire.send(), do NOT append the 0 byte. You will need to append one somehow if you want to pass your newly received string to a function like someFunction() above.
You should use a variable like
char myfile[12];
Another problem with writing a loop like
int i = 0;
while (0 < Wire.available())
{
myfile[i] = Wire.receive();
++i; // note this addition!
}
is that assumes that the data is arriving instantaneously. In other words, you are likely to exit the loop early because Wire.available() returns 0.
Solution: have the transmitter send the filename and follow with a "sentinel" (terminator) like:
Wire.send("filename.wav");
Wire.send(0);
On the receiving end try something like this:
int i=0;
while (true)
{
if (Wire.available())
{
byte b = Wire.receive();
myfile[i++] = b;
if (b == 0) break; // exit the loop when the sentinel arrives
}
}
Mikal
EDIT: Sorry westfw, I didn't mean to step on your toes.
In your example you initialize the myfile array but where is the null character then?
In C syntax, the null character is implicit when you use a string constant like "filename.wav".
does setting to "zero" mean they are full of null characters or full of the character/numer "0"?
Null characters or binary zero. (Not ASCII "0").
When you are reading in each character you stop writing to the array once you receive the '\r'
so if the string you read in is less than I am assuming that the rest of the array is still filled with the null characters so whatever function that reads from the array should stop reading once it hits those?
Yes! Your someFunction() will read up to the null character and stop.
or should you be doing this:
memset(myfile, '/0', sizeof(myfile)); ?
or
memset(myfile, '/r', sizeof(myfile)); ?
The first one. westfw's example only used the \r (note that's a BACKslash) to terminate the SERIAL transmission, but the null byte or \0 always terminates a string which is stored in memory.
My confusion with the zero is cleared up. as well It is character number 0 (the first one in the ascii set) not the character '0' and it is sent as an int value.