-17

Edit3: I intend to return to this to simplify the question and run through the list of responses in which the same answers keep recurring so as to explain why they don't work.

Edit: Explanation for why the question is unique: None of the other answers to the question answer the question. The question is unanswered. Basically as I can express it:

  1. There is a const string = "Hello";
  2. How to I get the string length at compile time?

Edit2: I've asked the question here again because I'm inundated with solutions which don't work. I'm getting exhausted with repeat explanations of why they don't work. The only answer which works is exactly what I had before I came here to find a better way of doing it.

The basic scenario which I cannot change is this:

I have a string declaration ( it's mandated this way ):

const string LETTERS = "Random Sentence";

Next, I need to perform a series of separate operations on the string.

So, what I'm doing is trying to declare a second mutable string to be the container for the outcome of those operations:

e.g. string ALPHABETICISED[15];

But, that is unwise. If it were a long program and I change the candidate LETTERS, then I must not forget to change the 15 to the new value manually. If there are several cases, it's accident prone.

What I'd like to do is something like:

int size = (int)LETTERS.length();
string alphabeticised[size];

But that is invalid, for two reasons:

  1. It would make an array of strings, it won't set the length of one.
  2. It won't evaluate at compile time anyway, so it will throw a non-constant expression error when I try to compile it because it doesn't have a substitution value yet.

Some recommendations use a constexpr, which would help, except for the fact it must compile against MSVC 2012, which basically limits me to c++98 convention. In any case, I can't use a constexpr in MSVC 2012.

Also, and for similar reasons, I'd like to use this size in the loops which will operate on the string, for example:

for ( int x = 0; x < LETTERS.length(); x++ ) {
    // Do stuff, for random example:
    incremented[x] = ++LETTERS[x];
}

Again though, I :shouldn't: need to find LETTERS.length at runtime! I already know what it will be every time.

So, how do I discover and use the string length at compile time, so I dont' have to find it during run time?

Caveats:

The solution must compile against MSVC 2012, which is roughly c++98 compliant and with very scant C++11 features, not even constexpr.

Also, I have no access to a debugger so I can't find out, as in a similar questions, if the compiler has subbed LETTERS.Length() for a constant expression.

In short, how to I declare a new string with the same length as a constant string with known length at compile time against MSVC 2012?

It seemed so simple! People must need to do this all the time? Allocate some volatile memory for a the result of an operation on a nonmutable array?

Georgina Davenport
  • 189
  • 1
  • 2
  • 11
  • Just use a `std::vector`: `std::vector alphabeticised(size);`. – πάντα ῥεῖ Mar 21 '16 at 20:36
  • 3
    I do not see the relation to StackExchange. – knivil Mar 21 '16 at 20:36
  • A new string with the same length as a constant string? `char *my_string[sizeof(constant_string)+1];` – ForceBru Mar 21 '16 at 20:37
  • @ForceBru That's not a string. It is an array of pointers. – juanchopanza Mar 21 '16 at 20:44
  • 1
    @juanchopanza, oops, I meant `char [sizeof(...)]` – ForceBru Mar 21 '16 at 20:45
  • That doesn't work ForceBru hence the question! – Georgina Davenport Mar 21 '16 at 20:45
  • *"what I'm doing is trying to declare a second mutable string "* So why do you then go to declare an array of strings? This makes very little sense. See the answers to your previous questions. – juanchopanza Mar 21 '16 at 20:46
  • Yeah... fine.... and the "..." what will you literally put there? – Georgina Davenport Mar 21 '16 at 20:46
  • @ForceBru Well, that wouldn't work at all. – juanchopanza Mar 21 '16 at 20:47
  • @GeorginaDavenport, `char string[sizeof(your_constant_string)+1]` – ForceBru Mar 21 '16 at 20:47
  • I don't do that juanchopanza as explained in the question above. I asked again because none of the other people have suggested an answer that actually works. – Georgina Davenport Mar 21 '16 at 20:47
  • Except for the #define style, but surely I can avoid #define? – Georgina Davenport Mar 21 '16 at 20:47
  • @juanchopanza, why? An array of chars, why not? – ForceBru Mar 21 '16 at 20:47
  • 3
    @GeorginaDavenport Because they have no idea what you're trying to do. Because your question makes absolutely no sense. – juanchopanza Mar 21 '16 at 20:48
  • @ForceBru Because the size is most likely not right. – juanchopanza Mar 21 '16 at 20:48
  • ForceBru. The trouble with that solution is it requires me to type the same string twice. What if I change the first one? I need that same string in the original definition. If I change the original define then it won't also change the duplicate in the sizeof directive. It's buggy. – Georgina Davenport Mar 21 '16 at 20:50
  • @juanchopanza, then `sizeof(string)/sizeof(string[0])`, maybe? – ForceBru Mar 21 '16 at 20:50
  • 2
    @ForceBru No. Please stop this. OP is already confused enough. – juanchopanza Mar 21 '16 at 20:51
  • Ah, okay, no problem – ForceBru Mar 21 '16 at 20:51
  • No, I'm not confused. And somebody has already Completely understood the question and come up with the #define solution, which works. But I think there must be a compliant way of getting the same result. That's all. – Georgina Davenport Mar 21 '16 at 20:55
  • 1
    If you aren't confused, please post a question that makes sense. – juanchopanza Mar 21 '16 at 20:56
  • It makes very simple sense: 1. There's a const declaration: const string blah = "string";. 2. How do you declare another string the same length? – Georgina Davenport Mar 21 '16 at 20:57
  • 2
    Use the `string` constructor that takes the string length as a parameter. [cppreference](http://en.cppreference.com/w/cpp/string/basic_string/basic_string) has some more on this. (Look at constructor (2)). – callyalater Mar 21 '16 at 20:57
  • 1
    What's wrong with just `std::string alphabeticised = LETTERS;` ?? I think you might need some more help on understanding the `std::string` vs. a `char[]` .. – txtechhelp Mar 21 '16 at 21:02
  • This is getting really frustrating... callyalater, that doesn't work. Not being Able to get the string length is the problem! The questions is: How do you get the string length at compile time? – Georgina Davenport Mar 21 '16 at 21:02
  • txtechhelp Yes, that is exactly the version I started with. That version works and I may go back to it. I asked again because the new string doesn't need to be assigned: It doesn't need content, it just needs size. The content will be immediately overwritten. Is there a way to just assign the size? – Georgina Davenport Mar 21 '16 at 21:04
  • The constraint of *compile time* length resolution is what is the problem here. `string` is a runtime allocated object and therefore its properties are not resolved at compile time. So you are asking for something that C++ doesn't already handle with string objects. – callyalater Mar 21 '16 at 21:06
  • callylater, what, even a const string? Which can't be changed? The point here cally is the string literal itself in const and never changes. It is known at compile time. I know about string, that's why you can't just string.length at compile time. That isn't what I want though. All I want is a method to find that known string length at compile time. – Georgina Davenport Mar 21 '16 at 21:09
  • 4
    @GeorginaDavenport, you fail to understand some of the concepts being explained about the type you have (which is probably why this being voted to be closed), you're refuting what the community is explaining without doing any basic research to understand why you can't do what you want. `All I want is a method to find that known string length at compile time` and that's not possible in C++ with exactly `const string LETTERS = "Random Sentence";` .. – txtechhelp Mar 21 '16 at 21:15
  • Well, you're not quite right because you can use sizeof which will find it at compile time, thanks. So I already know that I can, the only caveat with it is that it requires a #define. I'll ask you again in simplified form: 1. There's a const declaration: const string blah = "string";. 2. How do you declare another string the same length? That's the question. What's the answer? – Georgina Davenport Mar 21 '16 at 21:17
  • 1
    Possible duplicate of [Computing length of a C string at compile time. Is this really a constexpr?](http://stackoverflow.com/questions/25890784/computing-length-of-a-c-string-at-compile-time-is-this-really-a-constexpr) – txtechhelp Mar 21 '16 at 21:18
  • 1
    Possible duplicate of [String.length woes](http://stackoverflow.com/questions/36136843/string-length-woes) – callyalater Mar 21 '16 at 21:19
  • txt, it ISN'T a duplicate of that question. I'm using a system which means I can't use those answers and I'm exhausting myself explaining it time and time again. – Georgina Davenport Mar 21 '16 at 21:19
  • cally... nobody has answered that question and it's clogged with spam comments. Hence trying afresh. – Georgina Davenport Mar 21 '16 at 21:20
  • 3
    Why do you *need* to know the length at compile time? – callyalater Mar 21 '16 at 22:04
  • Why do you need to know why I need to know? Will you answer the question? Or just keep derailing the discussion with endless heckles? I need to know because I don't want to calculate the length of something at run time that is already a known at compile time: It's a waste of CPU time when it could be a const int before the program starts. So, how do you find the string length at compile time, not run time? – Georgina Davenport Mar 21 '16 at 22:19

1 Answers1

4

I don't see any issue there?

string incremented = LETTERS;  // modifiable string of exactly the same length as LETTERS
// or
string incremented(LETTERS.length(), 0);
for ( int x = 0; x < LETTERS.length(); x++ ) {
    // Do stuff, for random example:
    incremented[x] = LETTERS[x] + 1;
}

Compiles even in MSVC 2008.

If you are bothered by the fact that the modifiable string is allocated on the heap, take into account that the original LETTERS string is allocated on heap as well (and the C literal copied into the allocated memory). Unless the small string optimization is implemented and the memory of the original string is allocated on stack (and in that case the memory of the second modifiable string will be allocated on the stack either).

To allocate without initializing anything upfront, you can do as well:

string incremented;
incremented.reserve(LETTERS.length());
for ( int x = 0; x < LETTERS.length(); x++ ) {
    // Do stuff, for random example:
    incremented += LETTERS[x] + 1;
}
EmDroid
  • 5,918
  • 18
  • 18
  • Yep, actually that's the way I started before posting the question. My only problem with it is that it assigns the const string to the mutable string. That's why I rejected it. I did it that way at first and came here because the new string only needs the length of the old one, not the actual content. Is there a way to assign the size without the content? – Georgina Davenport Mar 21 '16 at 21:07
  • @GeorginaDavenport Yes, you were shown how to do that [in a previous question of yours](http://stackoverflow.com/questions/36136843/string-length-woes). – juanchopanza Mar 21 '16 at 21:08
  • @GeorginaDavenport, http://www.cplusplus.com/reference/string/string/resize/ – ForceBru Mar 21 '16 at 21:08
  • You keep on repeating the same thing ForceBeu: I don't have any trouble assigning the string size, the trouble is finding the length of a const string already assigned. It's Finding the length I need to do, not assigning it. – Georgina Davenport Mar 21 '16 at 21:12
  • I'm not using this string incremented(LETTERS.length(), 0); I don't need it. I'm using this: string incremented = LETTERS; That is All I'm using from this answer and it's Identical to what I already had before I asked the fist time. The whole point of coming here is to find a better way which only assigns the size. – Georgina Davenport Mar 21 '16 at 21:15
  • See the edit in the answer on how to just pre-allocate without initializing the memory (then += is used instead of index access to "add" the character). – EmDroid Mar 21 '16 at 21:17
  • @GeorginaDavenport, what's wrong with `string.size()`? Or just hard-code that length and change when appropriate – ForceBru Mar 21 '16 at 21:18
  • Haven't I explained it clearly enough already? I can't allocate an array size using string.size() at compile. Wanting to do that is the entire point of the question. Isn't it obvious enough? If I char wordscopy[WORDSCONST.size()]; it will throw a "expected constant expression" error. That's why. – Georgina Davenport Mar 21 '16 at 22:23