Attributes selected by name - char and pointers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-17
12:27 AM
- last edited on
ā2022-11-30
10:50 AM
by
Daniel Kassai
I'm trying to select attributes by name. I based it on Example I and II in AttributeGet docs.
After a while, I had Example 2 working but... It's doing well for all strings which have same beginning. So T, TE, TES, TEST all of them work. I assume its char handling but I'm not sure how to make it work.
Instead of the header.name I tried UniString pointer but referencing causes AC crashed.
Here is my try:
/* Example II -- loop through all attributes of a kind */ API_Attribute attrib; short nLin, i; GSErrCode err; BNZeroMemory(&attrib, sizeof(API_Attribute)); attrib.header.typeID = API_CompWallID; err = ACAPI_Attribute_GetNum(API_CompWallID, &nLin); for (i = 1; i <= nLin && err == NoError; i++) { attrib.header.index = i; err = ACAPI_Attribute_Get(&attrib); if (err == NoError) { char TTT[100] = "TEST"; int TTT_Idx; char AttTxt = *attrib.compWall.head.name; if (AttTxt == *TTT) { DGAlert(DG_INFORMATION, "ERR1", "ATTRIB GUT", "", "Good"); TTT_Idx = attrib.compWall.head.index; }Example 1 didn't work at all. I tried building header but search ends up with an error.
//Example I API_Attribute attrib; BNZeroMemory(&attrib, sizeof(API_Attribute)); char TTT[256] = "TEST"; attrib.header.name[256] = *TTT; err = ACAPI_Attribute_Search(&attrib.header); if (err == NoError) { char msgStr[512]; sprintf(msgStr, "[%d] %s", attrib.header.index, attrib.header.name); ACAPI_WriteReport(msgStr, true); DGAlert(DG_INFORMATION, "ERR1", msgStr, "", "Good"); } else { DGAlert(DG_INFORMATION, "ERR1", "error", "", "Good"); }Please help

Solved! Go to Solution.
- Labels:
-
Add-On (C++)
Accepted Solutions

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-17 10:58 AM
In "Example II" you made the mistake here:
kzaremba wrote:This way you copied only the first character of the attrib.compWall.head.name string to the AttTxt variable and in the if statement you compared only the first character of TTT to AttTxt.
/* Example II -- loop through all attributes of a kind */ ... char AttTxt = *attrib.compWall.head.name; if (AttTxt == *TTT) { ...
This would be correct:
/* Example II -- loop through all attributes of a kind */ ... if (strcmp (attrib.compWall.head.name, TTT) == 0) { ...You don't need the AttTxt variable and you can compare (char*) strings using strcmp method.
But to search attributes with a specific name the ACAPI_Attribute_Search function is recommended, so your other example code fits better for this purpose.
You made mistake in your "Example I" here:
kzaremba wrote:This way only the first character from TTT will be copied.
//Example I ... char TTT[256] = "TEST"; attrib.header.name[256] = *TTT; ...
Use strcpy method to copy the whole string:
//Example I ... strcpy (attrib.header.name, "TEST"); ...

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-17 10:58 AM
In "Example II" you made the mistake here:
kzaremba wrote:This way you copied only the first character of the attrib.compWall.head.name string to the AttTxt variable and in the if statement you compared only the first character of TTT to AttTxt.
/* Example II -- loop through all attributes of a kind */ ... char AttTxt = *attrib.compWall.head.name; if (AttTxt == *TTT) { ...
This would be correct:
/* Example II -- loop through all attributes of a kind */ ... if (strcmp (attrib.compWall.head.name, TTT) == 0) { ...You don't need the AttTxt variable and you can compare (char*) strings using strcmp method.
But to search attributes with a specific name the ACAPI_Attribute_Search function is recommended, so your other example code fits better for this purpose.
You made mistake in your "Example I" here:
kzaremba wrote:This way only the first character from TTT will be copied.
//Example I ... char TTT[256] = "TEST"; attrib.header.name[256] = *TTT; ...
Use strcpy method to copy the whole string:
//Example I ... strcpy (attrib.header.name, "TEST"); ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-20 05:29 PM
Thanks a lot, I have struggled with chars for a while. Example I works as a charm!
I couldn't get Example II working. strcmp gets violet in VS and got this description "strcmp_DISABLED!!!" and compiler error C2065.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-21 02:53 PM
Yes, strcmp is disabled in add-on sources. You can use the CHCompareCStrings function instead, which has a similar set of arguments, and produces identical results.
Best regards,
DƩnes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-22 03:24 PM
Right now I struggle a lot with char/std::string/GS::String conversions. What is the best practice in your opinion to handle chars and string? Using standard lib or GSRoot? Does it make any difference?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-22 04:01 PM
Using GS::UniString is the preferred method, as it is used in the API function calls and structures, and it uses UTF-8 encoding.
Also, you can use it in a similar fashion as you would use the std::string class, and you can use the GS::UniString::Printf static function instead of sprintf to construct a GS::UniString instance.
If you need a zero-terminated C string, you can convert a GS::UniString to a const char * by using the ToCStr method.
GS::UniString myStr = "Hello, world!"; // ... FunctionTakingCStr (myStr.ToCStr ().Get ());
Best regards,
DƩnes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā2018-08-24 02:29 PM
