1

** Update

I was trying to understand how/why XCode appears to be adding a weird character to my C++ source when in fact it was removing it. I am creating a simple class and using the CATCH2 testing framework as I work through a C++ course. I have a numwords class that converts numbers to words.

using namespace std;
//int main( int argc, char ** argv )
TEST_CASE("Numwords example", "[numwords]")
{
    bw::numword nw;
    uint64_t n;

    n = 3; REQUIRE( string(nw.words(n)) == "three");
    n = 47; REQUIRE( string(nw.words(n)) == "forty-seven");
    SUCCEED();
}

It was failing with:

/Users/c.craig/Training/CPP/Working/Working/numword-test.cpp:21: FAILED:
  REQUIRE( string(nw.words(n)) == "forty-seven" )
with expansion:
  "forty-seven" == "forty-seven"

Then I discovered by carefully copying/pasting the expected value back into my test that there indeed was some invisible difference. That's when it magically started to pass. I looked at my git diff and saw this:

diff --git a/Working/numword-test.cpp b/Working/numword-test.cpp
index c8f58db..3643c03 100755
--- a/Working/numword-test.cpp
+++ b/Working/numword-test.cpp
@@ -18,5 +18,5 @@ TEST_CASE("Numwords example", "[numwords]")
     uint64_t n;

     n = 3; REQUIRE( string(nw.words(n)) == "three");
-    n = 47; REQUIRE( string(nw.words(n)) == "forty-seven^P");
+    n = 47; REQUIRE( string(nw.words(n)) == "forty-seven");
 }

This weird control character only shows in the diff and only after I attempt to copy/paste the text from either the diff or the console after a failure. Adding the special character causes the test to pass. If I manually type the value "forty-seven" on my keyboard the the special character goes away and it FAILS. What in the world is happening? What is this ^P hidden character?

The source to numword.cpp is below:

#include "numword.hpp"

using namespace bw;
using namespace std;

numword::numword(uint64_t num) : number(num) {
}

static const char * unk = "?";

static const char * ones[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
static const char * tens[] = {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};

const char * numword::words(uint64_t num) const {
    std::string asString;

    if(num < 20)
        asString = string(ones[num]);
    else if(num < 100){
        int index = ((int)num/10)-2;
        int x = ((int)num%10);
        asString += string(tens[index]) + "-" + string(ones[x]);
    } else
        asString = unk;

    char *result = (char*)malloc(asString.length());
    memcpy(result, asString.c_str(), asString.length());
    return result;
}

I just did some research and discovered that ^P is a Data Link Escape code (DLE). I'm still not sure how to key it in. How is my numword.cpp logic adding it? Where am I going wrong?

Cliff
  • 10,586
  • 7
  • 61
  • 102
  • I've not seen that problem. I've been using Xcode for many years. However, I do often use Vim with my source code, so I cannot entirely vouch for Xcode's text editor. – Eljay Aug 17 '18 at 00:39
  • What's the source of `nw.words()`? – Steve Aug 17 '18 at 04:07
  • @Steve, I just updated with the nm.words code. – Cliff Aug 17 '18 at 05:45
  • @Eljay That tip on Vim helped! I just fired up vi and discovered that XCode was removing the special character, not inserting it. Indeed, it is the presences of the special character which causes the test to pass! Now I gotta figure out what the character is and how to type it! – Cliff Aug 17 '18 at 16:44

1 Answers1

0

I figured out my dilemma! The control character was an artifact due to how I was not null terminating my string from the words method. I've since added a nul terminator and the problem went away. (Please don't make mention of my obvious memory leaks here, I'm re-learning!)

The updated words method:

const char * numword::words(uint64_t num) const {
    std::string asString;

    if(num < 20)
        asString = string(ones[num]);
    else if(num < 100){
        int index = ((int)num/10)-2;
        int x = ((int)num%10);
        asString += string(tens[index]) + "-" + string(ones[x]);
    } else
        asString = unk;

    char *result = (char*)malloc(asString.length());
    memcpy(result, asString.c_str(), asString.length());
    result[asString.length()] = '\0';
    return result;
}
Cliff
  • 10,586
  • 7
  • 61
  • 102