[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 338
  • Last Modified:

C++ Get last 2 positions of a string

I need to check the last 2 positions of a string to be a certain value.  The actual position could vary.
0
pwiginton
Asked:
pwiginton
  • 7
  • 5
  • 5
  • +2
1 Solution
 
silemoneCommented:
you could get the length of the word first...
and then subtract by two for the first of the two characters
and then subtract by one for the last of the two characters.
0
 
silemoneCommented:
are you using string or char *?

either way they both have a Length() item...

last character would be at  string.Length() - 1
second to last would be at string.Length() - 2
0
 
silemoneCommented:
string word = "a word of varying length";
int 1stWord = word.Length() - 1;
char chFWord = word.charAt(1stWord); //this would be the value at that position...

if (chFWord == 'a'){}

//do this for second word...
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
mnhCommented:
Example code in C:

char str[] = "hello world!";
char *ptr = NULL;
int str_len;

str_len = strlen(str);
if (str_len >= 2)
{
    ptr = str + str_len - 2;
    if (!strcmp(ptr, "XY"))
    {
       /* If last two characters are XY, do your stuff here... */      
    }
}

Regards,
-- mnh
0
 
dimonicCommented:
for a plain C char *:

int len;

len = strlen(my_string);
if (my_string[len - 1] == something || my_string[len - 2] == somethingelse) {
    do something;
}

For a std::string:

int len = my_string.length();
if (my_string[len - 1] == something || my_string[len - 2] == somethingelse) {
    do something;
}
0
 
mnhCommented:
Example in C++:

if (str.compare(str.length - 2, 2, "XY") == 0)
{
    // If last two characters of str are XY, do your stuff here...
}

0
 
silemoneCommented:
dimonic, couldn't you essentially write the same code for char*?  I haven't used C in a long time, but wouldn't char * be an array where you could use it's length to get the last two values?  This is for my own knowledge base, but why would strlen be better than char * word[] = "Hello";
int x = word.Length();

thanks in advance...
0
 
mnhCommented:
Hi dimonic,

Your examples are not correct: they should have &&, not ||, since the question author needs to check the last 2 positions of the string to be a certain value.

Regards,
-- mnh
0
 
dimonicCommented:
silemone:
There are no member functions of a char *, a char * is a pointer to a built in type, not a class. (so .Length() would not exist) - and the std::string has a "length()" member function, not "Length()".
0
 
dimonicCommented:
mnh:

The original poster's question did not specify whether the two values both had to be the same, or whether either one could be a certain value. In the absence of clarity from the question, I assumed he/she would choose the appropriate logical operator. That said, you could be right - or I could be right. Only the original poster would know.
0
 
silemoneCommented:
char * is a pointer...I understand that, but I've worked with pointers that have pointer functions...so I didn't realize MS didn't create the same for the char *.

well, the user also specified c++ and i would conclude by '2 positions of a string' that he's working with the string class...He didn't specify which the framework though...6, or newer, so we will see...
0
 
pwigintonAuthor Commented:
I tried the solution from mnh.  Below is my code:

strncpy(Exprt.Description1, strDesc, 50);
if (strDesc.compare(strDesc.length - 2, 2, "CD") == 0)
{
     strncpy(Exprt.AssetTypeMajor, "CD  ", 4);
     strncpy(Exprt.AssetTypeMinor, "CD ", 3);
}

I get this compile error:

error C2228: left of '.length' must have class/struct/union type  type is 'char [50]'
0
 
mnhCommented:
Parenthese are missing from the length method. Should be like this:
if (strDesc.compare(strDesc.length() - 2, 2, "CD") == 0)
0
 
mnhCommented:
Additionally, for this to work strDesc must be of C++ type std::string.
0
 
mnhCommented:
Since it looks that strDesc is defined as char [50], I rhink you should try my C example.
0
 
pwigintonAuthor Commented:
I changed to use the C example.  Is there a way to trim the spaces on the right before doing the check?
0
 
mnhCommented:
Sure. Suppose

    char strDesc[50] = "Hello World!   ";

Then do the following:

     char *p = NULL;
     p = strDesc + strlen(strDesc) - 1;
     while(*p == ' ')
     {
        *p = '\0';
          p--;
     }
 
Now the trailing blank at the end of strDesc are gone.
From here proceed as described above.

Regards,
-- mnh
0
 
pwigintonAuthor Commented:
Thanks.
0
 
dimonicCommented:
/** \brief compare last two characters of string with 2 chars

    \param my_str  String to check last two characters of
    \param match 2 chars to match
    \return 0 if last two characters match, otherwise the difference between first non-matching chars.
    If you wish case insensitive, change the strncmp_s to strnicmp_s
*/
int MatchLast2Char(const char * my_str, const char * match)
{
    int len = strlen(my_str);

    return strncmp(my_str + len - len, match, 2) ;
}
0
 
evilrixSenior Software Engineer (Avast)Commented:
dimonic,

I suspect you probably meant

return strncmp(my_str + len - 2, match, 2) ;

Of course, if the length of the original string is < 2 chars this will not work as expected (in fact, the result of the function will be undefined since it will under-run into random memory that'll have random values) so you also need an additional check to protect against that too.

Ironically, the Microsoft "secure" (pah!) CRT doesn't protect against buffer under-runs yet these are just as dangerous as buffer-overruns (and, nearly as common). This is just one more good reason to avoid these stupid functions in favour of well know tried and tested posix/ansi standard functions.

-Rx.
0
 
dimonicCommented:
evilrx,

Yes, that is what I meant. My crying 7 mo old meant I didn't actually run my code, and yes, it is prone to a buffer underun, I usually write code for clarity on a "teaching" forum like this, but yuo are right - defensive is better.

int MatchLast2Char(const char * my_str, const char * match)
{
    int len = strlen(my_str);

    if (len < 2)
      return -1;
    return strncmp(my_str + len - 2, match, 2) ;
}
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 7
  • 5
  • 5
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now