• Advertisement
Sign in to follow this  

Char* string: How To??

This topic is 4142 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, here is my problem: I'm writing text on screen using OpenGL and I'm having problems with starting new lines. I wanted to write a code that tells the application to start a new line when it finds the string "XX"; Here is the code:
char * imputText = "BlaBla XXBlaBla";
char * reference = NULL;
reference = strstr(imputText, "XX");
if (reference == NULL) font->RenderFont(0, 0, font->m_fontListBase, imputText); //This writes the content of imputText at (0;0) on the screen;
else
{
   font->RenderFont(0, 0, font->m_fontListBase, (reference + 2)); //This writes the content of (reference + 2) at (0;0) on the screen;
   reference = '\0' //This should erase everything from the imputText string starting from the first X. Point is it does not work.
   font->RenderFont(0, 30, font->m_fontListBase, imputText); //This writes the content of imputText at (0;30) on the screen;
};


As reference is a pointer I don't see why imputText is not modified if reference is modified... perhaps it is not... so this is my problem: if i render this i get: BlaBla XXBlaBla BlaBla whereas I would like to get: BlaBla BlaBla Do you know how to solve this?? Thanks in Advance, Merlino.

Share this post


Link to post
Share on other sites
Advertisement
char * imputText = "BlaBla XXBlaBla";
char * reference = NULL;
reference = strstr(imputText, "XX");
if (reference == NULL) font->RenderFont(0, 0, font->m_fontListBase, imputText);
else
{
font->RenderFont(0, 0, font->m_fontListBase, (reference + 2));
reference = '\0' //This should erase everything from the imputText string starting from the first X. Point is it does not work.
font->RenderFont(0, 30, font->m_fontListBase, imputText);
};


refrence should equal a pointer to the string "XXBlaBla"
so, it will enter the else statement
in the else statement, it should render "BlaBla"
then it will empty render to null
and then it should print inputtext, which is still pointing to "BlaBla XXBlaBla"..


So, in order it is printing
BlaBla
BlaBla XXBlaBla

(refrence+2)
(imputtext)

as a side note, you spent "input" wrong?

also
char * reference = NULL;
reference = strstr(imputText, "XX");

should be
char * reference = strstr(imputText, "XX");
(your compiler will likely make it this way logically anyway.
No sense calling the default constructor on refrence if you are only going to replace it.

Share this post


Link to post
Share on other sites
i wrote this:
BlaBla XXBlaBla
BlaBla

just because in the window space, inputText is higher than (reference+2).
(Sorry about the input !! :P)

But, isn't reference equal to (inputText+7) ?
That's what i wanted to do:
1 - write the second line, using reference without the XX. [font->RenderFont(0, 0, font->m_fontListBase, (reference + 2));]
2 - change the value of inputText from: "BlaBla XXBlaBla\0" to BlaBla \0" so that the second BlaBla is not rendered 2 times. [reference = '\0']
3 - write the first line, using inputText. [font->RenderFont(0, 0, font->m_fontListBase, imputText);]

Clearly, what does not work is reference = '\0' meaning that reference is modified but inputText is not. And I don't understand why...

Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by Merlino
Clearly, what does not work is reference = '\0' meaning that reference is modified but inputText is not. And I don't understand why...


Because you're modifying "reference" and not "inputText." Y9u have answered your own question. Now try dereferencing the reference and see what you get.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Bregma
Quote:
Original post by Merlino
Clearly, what does not work is reference = '\0' meaning that reference is modified but inputText is not. And I don't understand why...


Because you're modifying "reference" and not "inputText." Y9u have answered your own question. Now try dereferencing the reference and see what you get.


You'll get a memory protection error.

Share this post


Link to post
Share on other sites
You have modified reference, not the string pointed to by reference and inputText. What I think you meant to do was:

*reference = '\0'


reference = '\0' will set the pointer named reference to NULL. *reference = '\0' will set the value of the character the pointer named reference points to to the end-of-text marker.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ozymandias42
You have modified reference, not the string pointed to by reference and inputText. What I think you meant to do was:

*reference = '\0'


reference = '\0' will set the pointer named reference to NULL. *reference = '\0' will set the value of the character the pointer named reference points to to the end-of-text marker.


That anonymous post above yours was mine, but I forget to log in. This is a char* string literal and it is not allowed to be modified through this pointer.



// char* inputText = "BlaBla XXBlaBla";
// should be

char inputText[] = "BlaBla XXBlaBla";

// and reference = '\0'
// should be

*reference = '\0';


Share this post


Link to post
Share on other sites
Quote:
Original post by Absolution
That anonymous post above yours was mine, but I forget to log in. This is a char* string literal and it is not allowed to be modified through this pointer.


Maybe, maybe not. Depends on the compiler, the platform, etc. Certainly quite likely, though. I was assuming it was example code, since if he were actually using a constant, there'd be no resaon to hunt down the XXs at runtime.

Share this post


Link to post
Share on other sites
Oh I see what you're trying to do!

char imputText [] = "BlaBla XXBlaBla";
reference[0]='\0';
font->RenderFont(0, 0, font->m_fontListBase, imputText);
font->RenderFont(0, 30, font->m_fontListBase, &reference[2]);

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Ozymandias42
Quote:
Original post by Absolution
That anonymous post above yours was mine, but I forget to log in. This is a char* string literal and it is not allowed to be modified through this pointer.


Maybe, maybe not. Depends on the compiler, the platform, etc. Certainly quite likely, though. I was assuming it was example code, since if he were actually using a constant, there'd be no resaon to hunt down the XXs at runtime.


I'm pretty sure string literals are constant:

Quote:
An ordinary string literal has type “array of n const char” and static storage duration
(3.7), where n is the size of the string as defined below, and is initialized with the given characters.


And stevenmarky, I thought my reply was concise, but maybe not.

Share this post


Link to post
Share on other sites
Ok, so in order to be able to modify imputText, I should declare it as an array and not as a pointer? It's not a problem actually in my program but having a pointer would be more space saving in a bigger project.

Ozymandias42, imputText it's not a constant of course: what I wanted to do is haivng a string which was modified based on the user imput.. and that's why it would have been nice not to have it with a set size.

Anyway, I think the array will work just fine. Thanks a lot everybody :D

Share this post


Link to post
Share on other sites
Well, unless you're keeping a extra copy, an array of characters is exactly the same size as a pointer to a string, since they're the same thing.

THe other folks are saying that
char* inputText = "BlaBla XXBlaBla";
wouldn't work because the blabla string is a constant, not because inputText is a pointer instead of an array. Making an array out of it will make it writable, but don't think you couldn't say
*inputText = '\0'
if inputText wasn't pointing to constant data.

Share this post


Link to post
Share on other sites
You appear to be using C++, so why don't you use C++ and use a std::string!

Σnigma

Share this post


Link to post
Share on other sites
Quote:
It's not a problem actually in my program but having a pointer would be more space saving in a bigger project.


Not quite certain what you mean, but in C (and therefore, presumably C++ since it's a reasonably notable thing), the array indexing and pointer dereferencing operators are both applied to a pointer. That is, if you define an array of ints as
int myarray[5]
, all that does is reserve 5 * sizeof(int) bytes on the stack, and gives you myarray as a pointer to that bit of memory. You can then use *myarray interchangeably with myarray[0].

Share this post


Link to post
Share on other sites
Quote:
Original post by Ozymandias42
THe other folks are saying that
char* inputText = "BlaBla XXBlaBla";
wouldn't work because the blabla string is a constant



Why and array of char would have a constant value?
Aren't chars just like ints? I read that they are just numbers that are then converted to letters...

Share this post


Link to post
Share on other sites
Quote:
Original post by Merlino
Quote:
Original post by Ozymandias42
THe other folks are saying that
char* inputText = "BlaBla XXBlaBla";
wouldn't work because the blabla string is a constant


Why and array of char would have a constant value?
Aren't chars just like ints? I read that they are just numbers that are then converted to letters...


"BlaBla XXBlaBla" is a litteral constant, just as 1, 10, or every other litteral constant in C or C++. The "..." mechanism is used to make string representation simpler (because you don't want to write {'.', '.', '.'}), but that doesn't change the fact that it is a constant.

Litteral string constant are not required by the standard to be mutable, thus the compiler may put them in a read-only part of the memory (for example, an initialized segment that will be write protected). This allow the compiler to have only one copy of this string in memory, and all the string that actually refers to this constant are in fact pointing to the same memory location. It means that by modifying this location, you actually change all the other strings that use the same litteral constant.

The other people are right, but this doesn't disallow you to use this litteral constant in your code. Remember that it's type is not "char*" but "const char*" and that you should not modify it by any mean and you're quite safe.

Actually, no, you are not that safe. As pointed out by both our lovely Zahlman and our dedicated Enigma, in C++ you should use std::string and its methods, not char* strings and a bunch of unsecure and obsolete C functions.

I repeat it and underline it: use std::string.

@Zahlman: why not changing your sig to state: As a general rule, if you post in any forum and your C++ code contains the word 'char', you have a bug. std::string roxors teh big one one one one.

(There is a missing C++ by the way. C doesn't have std::string [smile])

Share this post


Link to post
Share on other sites
char * text = "hello world";

"hello world" is what is known as a string literal.

int number = 10;

the 10 is an integer literal.

char alpha = 'a';

the 'a' is a character litereal.

float precise = 0.123f;

the 0.123f is a float literal.

And so on.

Literals Can Not be modified.. except in arrays.

int numbers[4] = {0,1,2,3};

This assigns the numbers to an array. Because they are in an array, they can be modified.

char grades[5] = ['A', 'B', 'C', 'D', 'E'};

This is a character array. The letters can be modified.

char text1[10] = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0};

char text2[10] = "hello world";
Those are both identical initializations. See, with character arrays the compiler allows you to cheat and use string literals as a short-hand for the text1 example. That is, text2 is just short-hand initialization for character arrays. This is the only case in which you can modify a string literal because it isn't Really a string literal with arrays. However, with char pointers, it Is a string literal.

Hopefully that clears things up.

Share this post


Link to post
Share on other sites
Quote:
Original post by TheUnbeliever
int myarray[5]
, all that does is reserve 5 * sizeof(int) bytes on the stack, and gives you myarray as a pointer to that bit of memory. You can then use *myarray interchangeably with myarray[0].


This is not perfectly true. An array in C is not a pointer, as can be seen from the low-level operations necessary to access one of its elements. To access element i in array a, add i to a and get the value there. To access element i in a buffer pointed to by p, get the value of p, add i to it, and get the value there.

A stack array requires one less memory access than a pointed-to buffer. Of course, this is usually incompatible with argument passing, so stack arrays decay into pointers. But they are not pointers.

Back to the topic: use std::string. You don't need char* in C++ to manipulate strings, and you apparently do not have the required level of experience to get reasonable performance out of char* anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Emmanuel Deloget

The other people are right, but this doesn't disallow you to use this litteral constant in your code. Remember that it's type is not "char*" but "const char*" and that you should not modify it by any mean and you're quite safe.

Actually, no, you are not that safe. As pointed out by both our lovely Zahlman and our dedicated Enigma, in C++ you should use std::string and its methods, not char* strings and a bunch of unsecure and obsolete C functions.

I repeat it and underline it: use std::string.

(There is a missing C++ by the way. C doesn't have std::string [smile])


It's ok, I got it :D
I understood, I just wanted to know a bit more .. just for culture.

I'll use arrays, just like text1 and text2 in nobodynews reply. Thanks again.


PS: Emm, does anybody know where I can find any std::string tutorials? I've looked on google but, since I live in france.. it gets to google.fr and I can't find much.. ^^

Share this post


Link to post
Share on other sites
Good thread. The same thing was repeated about 10 times by 10 different people. Sometimes that's what it takes though I guess.

Your example in the standard library:


#include<iostream>
#include<string>

int _tmain(int argc, _TCHAR* argv[]) {
std::string inputText= "BlaBla XXBlaBlaXXBlablaXXBlablabla";

std::string::size_type pos=0;
std::string::size_type old=0;

while((pos=inputText.find_first_of("XX",old))!=std::string::npos) {
std::string linestring=inputText.substr(old, pos-old);
std::cout << linestring << '\n';
old=pos+2;
}

if(old!=inputText.size())
std::cout << inputText.substr(old, inputText.size()-old) << '\n';
return 0;
}




That's one way of doing it. It just continually searches your string and tokenizes it.

If you like the standard libarary, you can then look into the boost library which has a tokenizer class that might do all of this for you (although I've never used it.)

[Edited by - Absolution on October 19, 2006 3:42:30 PM]

Share this post


Link to post
Share on other sites
Ok, one thing and then I'm done:
In my program, instead of outputing the string with cout I need to use a the OpenGL renderFont function;

Point is it only accepts a char* value;

So, to "convert" the string I tried to use .c_str();

Assuming that inputText is a std::string that's what I wrote:
font->RenderFont(0, 0, font->m_fontListBase, inputText.c_str());

If I use this function I get an error saying: "Invalid conversion from const char* to char*"

It smells like this has also been answered a million times.. ..I'm sorry ^^.

Problem Solved !!!
Changing the value type renderFont accepts from char* to const char* worked.

Again, thanks a lot for you patience and sorry for my ignorance.
Merlino

Share this post


Link to post
Share on other sites
You can also cast away constness with const_cast<char*>(inputText.c_str()).

Edit: forgot the .c_str().

[Edited by - Absolution on October 19, 2006 6:21:13 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement