Solved

# C++ Get last 2 positions of a string

Posted on 2009-12-21
322 Views
I need to check the last 2 positions of a string to be a certain value.  The actual position could vary.
0
Question by:pwiginton

LVL 21

Expert Comment

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

LVL 21

Expert Comment

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

LVL 21

Expert Comment

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

LVL 3

Accepted Solution

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

LVL 2

Expert Comment

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

LVL 3

Expert Comment

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

LVL 21

Expert Comment

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();

0

LVL 3

Expert Comment

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

LVL 2

Expert Comment

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

LVL 2

Expert Comment

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

LVL 21

Expert Comment

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

Author Comment

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

LVL 3

Expert Comment

Parenthese are missing from the length method. Should be like this:
if (strDesc.compare(strDesc.length() - 2, 2, "CD") == 0)
0

LVL 3

Expert Comment

Additionally, for this to work strDesc must be of C++ type std::string.
0

LVL 3

Expert Comment

Since it looks that strDesc is defined as char [50], I rhink you should try my C example.
0

Author Comment

I changed to use the C example.  Is there a way to trim the spaces on the right before doing the check?
0

LVL 3

Expert Comment

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

Author Comment

Thanks.
0

LVL 2

Expert Comment

/** \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

LVL 39

Expert Comment

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

LVL 2

Expert Comment

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

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were smallâ€¦
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn hoâ€¦
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.