I'm attempting to make a method that will take the argument const char string[] from the user. this parameter. will then be outputted via a for loop to the screen character by character until the string has reached it's length.
I need to know the length of the string in order for my loop to work. for instance, if the length is 6, the loop should run 6 times, and display 6 characters onto the display.
I would have used a foreach loop for this, but I'm actually in the GBA environment and for some reason for each loops don't compile correctly. So I'm trying to use .strlen() instead to get the length of the string.
However, I cannot use the .strlen() method because my const char string[] isn't a string.
With all the above in mind, How can I use the .strlen() method in the following code?:
void DrawText(int x, int y, const char string[])
{
for(int i = 0; i < string.strlen(); i++)
{
SetTile(0, x + i, y, 70);
}
}
You can use std::strlen(string) from the cstring header, but only if string points to a null-terminated char array.
Related
Background
I've written an Arduino function which receives strings in the format "a,b,c,d,e" over a serial connection, where a,b,c,d,e are integers, and I'm trying to update an array with these integers every time a new string is received. The data is received and parsed into individual integers fine, but the array won't update properly.
Attempt
Below is the code, I've left the getData() function out as all it does is receive the string from the serial connection and store it in an array of characters input (that part is working fine).
void setup() {
Serial.begin(9600);
}
void loop() {
getData();
if(parsed == false){
parseData(readings);
}
}
void parseData(int readings[]) {
x = 0;
char * split;
split = strtok(input,",");
while (split != NULL)
{
readings[x] = split;
split = strtok (NULL, ",");
x++;
}
parsed = true;
}
Problem
If I send a string like "6,7,8,9,0", the array readings[] is updated to [289,291,293,295,297] no matter what values I send, I have checked what values split takes inside the function and they are correct, however the line readings[x] = split; fails to update the array elements to anything other than those 5 numbers in that order. This is the case when the value of readings[n] is checked inside or outside the parseData function.
Also, if I send fewer than 5 integers in the string, e.g. a,b,c, only the first array elements will change and the others will remain at 0, e.g. [289,291,293,0,0]
Before I found out about passing array pointers to functions, the exact same thing was happening with slightly different code - when I called the function in the loop, I just used parseData();, and when I defined the function I just used void parseData(){
Question
Why isn't the array updating properly and how can I fix it?
Your readings is an array of integers.
And split is a pointer-to-char.
The statement
readings[x] = split
stores split, which is the address of a character, as an integer value.
If I write
const char *pointer = "42";
int address = pointer;
I am not storing the integer value 42 in address - I'm storing the number identifying the memory location of the first character in my string.
If you want to convert a string into an integer, you need to parse it with a function like strtol.
I am working on a project that takes a Lua string and converts it into a C string – not at all difficult, of course. However, I run into trouble when attempting to convert a binary representation of a function, i.e. one produced by a call to string.dump, to a C string. I am having trouble reading the entire string.
While it is not the ultimate goal of the project, consider the following simple example where I print out the characters in a string one-by-one using a C function called chars that I have registered for use in Lua:
static void chars(char* cp) {
char* pointer = cp;
while (*pointer) {
printf("%c\n", *pointer);
++pointer;
}
return;
}
static int lua_chars(lua_State* L) {
lua_len(L, 1);
size_t len = static_cast<size_t>(lua_tonumber(L, -1)) + 1;
lua_pop(L, 1);
if (len > 0) {
char* cp = static_cast<char*>(malloc(len));
strcat(cp, lua_tostring(L, 1));
chars(cp);
free(cp);
}
return 0;
}
Calling chars from a Lua script would look like this:
chars("Hello World!")
and would print out the characters one by one with each followed by a newline.
Now to the actual issue. Consider this example where I declare a function in Lua, dump it with string.dump, and then pass that string to the function chars to print out its characters individually:
local function foo()
print("foo")
return
end
local s = assert(string.dump(foo))
chars(s)
The string s in its entirety, not printed with my function chars, looks something like this:
uaS?
xV(w#=stdin#A#$#&?&?printfoo_ENV
However, chars only prints the first five bytes:
u
a
S
(Note there are supposed to be two lines of whitespace before the 'u'.)
I am almost certain that this is due to null characters within the string, which I think interferes with lua_tostring's functionality. I have come across lua_Writer for reading chunks, but I have no idea how to use/code it. How can I successfully convert the entire string on the Lua stack to a C string?
I am almost certain that this is due to null characters within the
string
Yes, it's exactly because Lua strings can contain zeroes.
which I think interferes with lua_tostring's functionality.
And this is false. lua_tostring() works as intended. It's just strcat() you're using will only copy the data up to the nearest zero byte.
If you need to copy the string, use memcpy, passing it both the pointer to Lua string data and Lua string length (lua_len, lua_rawlen, etc).
But just for printing you don't even need to copy anything. Pass the len variable as an argument to chars(), and check that length instead of waiting for zero byte.
The Problem isn't lua_tostring but strcat which copies until it finds an null characters. Same Problem with your chars function.
That should work:
memcpy(cp, lua_tostring(L, 1), len);
chars(cp, len);
...
static void chars(char* cp, size_t len) {
for (size_t i = 0; i < len; ++i, ++cp) {
putchar(*cp);
}
}
I'm trying to create a binary representation of a string of characters but could only print them using serial.print(arr,BIN);
Is there a way to save the binary values of each char of the string to an array or even a long number?
* Working on Arduino sketch (C++) if it makes any difference.
I used this code trying to create an array but couldn't make it work:
void loop() {
String Message = "Hello World";
int l = Message.length();
int BinMessage[l];
for (int j=0; Message[j] != NULL; j++){
BinMessage[j] = String(Message[j], BIN);
Serial.println(BinMessage);
}
One option might be to use bitRead function to read the bits of each character one by one, then store those values as characters in a new string.
I want to use regex on a binary file, which contains 0 bytes, which renders me unable to use a string. I'm using a char array, and I'm able to use regex on the char array.
Buffer is a copy of the file mapped into memory, and read is the total size. This code works, but now I want to get the result back from the function. How do I do this?
if(std::regex_search(buffer, buffer + read, *params->pattern))
{
std::cout << "Found.";
}
I did not test this but it should work..
auto it = std::cregex_iterator(&buffer[0], &buffer[read], *params->pattern);
for (int i = 0; i < it->size(); ++i)
{
const char* str = (*it)[i].str();
size_t size = (*it)[i].length();
std::cout.write(str, size);
}
I've tested this only on regular strings.. Not strings containing null chars. I don't see why it shouldn't work though because it does return a sequence of chars and the length of said sequence.
I'm making a lexical analyzer and this is a function out of the whole thing. This function takes as argument a char, c, and appends this char to the end of an already defined char* array (yytext). It then increments the length of the text (yylen).
I keep getting segfaults on the shown line when it enters this function. What am I doing wrong here? Thanks.
BTW: can't use the strncpy/strcat, etc. (although if you want you can show me that implementation too)
This is my code:
extern char *yytext;
extern int *yylen;
void consume(char c){
int s = *yylen + 1; //gets yylen (length of yytext) and adds 1
//now seg faults here
char* newArray = new char[s];
for (int i = 0;i < s - 1;i++){
newArray[i] = yytext[i]; //copy all chars from existing yytext into newArray
}
newArray[s-1] = c; //append c to the end of newArray
for (int i = 0;i < s;i++){ //copy all chars + c back to yytext
yytext[i] = newArray[i];
}
yylen++;
}
You have
extern int *yylen;
but try to use it like so:
int s = (int)yylen + 1;
If the variable is an int *, use it like an int * and dereference to get the int. If it is supposed to be an int, then declare it as such.
That can t work:
int s = (int)yylen + 1; //gets yylen (length of yytext) and adds 1
char newArray[s];
use malloc or a big enought buffer
char * newarray=(char*)(malloc(s));
Every C-style string should be null-terminated. From your description it seems you need to append the character at c. So, you need 2 extra locations ( one is for appending the character and other for null-terminator ).
Next, yylen is of type int *. You need to dereference it to get the length (assuming it is pointing to valid memory location ). So, try -
int s = *yylen + 2;
I don't see the need of temporary array but there might be a reason why you are doing it. Now,
yytext[i] = newArray[i]; //seg faults here
you have to check if yytext is pointing to a valid write memory location. If yes, then is it long enough to fill the appending character plus null terminator.
But I would recommend using std::string than working with character arrays. Using it would be a one liner to solve the problem.