0

In C one can declare a char array, create a pointer to a specific location in the array, and dereference it to get a suffix in the specified position:

char str[6] = "SLEEP"; char* pointer = &(str[1]); printf("%s\n", pointer); 

The above code will print

LEEP 

which is the suffix of "SLEEP" in position 1. Now is there a way to do something similar in C++ without using the substr method as it produces a completely new string and I'm trying to avoid that.

7
  • 3
    So, C or C++? Pick one. Commented Jul 17, 2013 at 20:05
  • 1
    Use an iterator pair. Commented Jul 17, 2013 at 20:07
  • 1
    std::string str("SLEEP"); char* pointer = &(str.c_str()[1]); printf("%s\n", pointer); Commented Jul 17, 2013 at 20:08
  • @madnut, Except it's not modifiable. Commented Jul 17, 2013 at 20:09
  • @chris Technically it is modifiable but lets say it shouldent be modified this way :) Commented Jul 17, 2013 at 20:15

4 Answers 4

8

You can do exactly what you've already done.

char str[6] = "SLEEP"; char* pointer = &(str[1]); printf("%s\n", pointer); 

If you are using a std::string instead of a raw char buffer (like you should be), then under C++11 std::string is guaranteed to have contiguous storage (21.4.1/5) with an appended NUL terminator (21.4.7.1/1):

std::string str = "SLEEP"; const char* pointer = &str[1]; 

These guarantees are new to C++11 -- C++03 makes no such guarantees. However all implementations I'm aware of do in fact use contigious storage with an appended NUL terminator. They do this because c_str() is required to return a const pointer to a C-style string. If you want a solution that is guaranteed to be compliant in C++03, then std::vector makes the same contiguity guarantee, even in C++03, but of course there you must apply the NUL terminator on your own:

std::string load = "SLEEP"; vector <char> str; copy (load.begin(), load.end(), back_inserter (str)); load.push_back ('\0'); // Appended NUL terminator const char* pointer = &str [1]; 

But now we're talking about making copies, obviously.

Sign up to request clarification or add additional context in comments.

11 Comments

I added one to string address, see "SLEEP"[1] == 'L', or "SLEEP"[1] == *("SLEEP" + 1) so for address of "SLEEP"[1] I did, "SLEEP" + 1.
@GrijeshChauhan, It's valid, just not as apparent to most people.
@chris: It's valid, but not at all resemblant to what the original question suggested was the desired code. Hence my "wait, what?"
@chris, John I means by this is this code I written in C, but I wish to add an answer here in C++
@GrijeshChauhan: So you're asking me if the code you want to post as an answer is technicall correct before you risk the downvotes by posting it yourself? Weak sauce.
|
3
#include <string> #include <iostream> int main() { std::string s("SLEEP"); std::cout << &s[1] << std::endl; } 

This is guaranteed to work in C++11. In C++03, no such guarantees exist, since implementations are allowed to use copy on write (COW). But I don't recall working with an implementation where this didn't work. If you use C++03 and need the guarantee, you will can use the std::string::c_str():

std::cout << &s.c_str()[1] << std::endl; 

8 Comments

Works for sure in C++11 :)
Not guaranteed in C++03.
@JohnDibling Thanks, I added a line about that. I tend to think in C++11 on SO, to compensate for not being able to use it at work.
@GrijeshChauhan not really, because it is dealing with an std::string, not a string literal. I interpret the question to be about std::string, but I could be mistaken.
@GrijeshChauhan I know what you meant. I am talking about std::string here, so what you are showing is not equivalent.
|
0

you can use the array method if you want. The example I give is C++.

for example MyStr[0] is the pointer to the first element.

#include <string> #include <iostream> int main() { std::string MyStr="abc"; std::cout<<&MyStr[1]; } 

output: bc

Hope that helps :-)

Comments

0

You can use a string reference class. A string reference class provides string-like functionality but doesn't actually own the underlying storage.

Here's an example using the Boost string_ref class (found in Boost.Utility)

#include <iostream> #include <string> #include <boost/utility/string_ref.hpp> int main(int argc, const char * argv[]) { using namespace std; string str = "SLEEP"; cout << "str: " << str << endl; boost::string_ref sr1(str); cout << "sr1: " << sr1 << endl; boost::string_ref sr2 = sr1.substr(1); cout << "sr2: " << sr2 << endl; return 0; } 

Note: there in only one actual instance of the string "SLEEP". sr1 and sr2 are string references into str.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.