Modifying string literals for recursive function [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I've got a recursive function that is supposed to check if a given word is a palindrome, which works by comparing the first and last value, then strips them off and passes them recursively into checkPalindrome, but whenever I try to assign word[size-1] to '\0', I get a Bus Error.
Here is my code:
bool checkPalindrome(char word[]){
int size = std::strlen(word);
//Parts removed...
word[size-1]='\0'; //This is the line causing the issue
return checkPalindrome(word+1);
}
}
Here is an example of a call to this function:
checkPalindrome("racecar");
Thank you!

There are two ways I can think of to solve this problem:
The obvious one would be to use a std::string instead of a string literal and just .pop_back() (C++11) to remove the last character.
The second would be to pass the length of the string to the function as a parameter, instead of computing it. Then, just decrease the length by 1 so now you have a new "fake end point" to the string. Since you're using this number to check the last character, you don't really need to actually modify the string, just change where the "last" character is.
But since you're using C++, I don't see why not use std::string and avoid overcomplicating the problem.

So as stated in the comments you can't modify a string literal.
So before passing it to the function, make a copy of it.
std::size_t len = std::strlen(word);
char* copy = new char[len + 1];
std::strncpy ( copy, word, len + 1 );
isPalindromeR(copy);
delete[] copy;
other solution would be to not use recursion, thus not needing to modify the string.
anyway outside of assignments use a std::string

Related

Getting initializer-string for char array is too long. Is this a compiler error? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
static_assert(0<decltype(AType::Id)::MaxIdLen);
using __type = char[decltype(AType::Id):: MaxIdLen + 10000];
[[maybe_unused]] __type aa = ""; //error initializer-string for char array is too long
I am getting this weird compiler error saying the initializer string is too long. But it is actually not. The first static_assert passed.
Has anyone seen such an issue before? I am using clang.
... compiler error saying the initializer string is too long. But it is actually not.
The compiler is not telling you that the string is too long to init aa. It's telling you that it's more data than it can handle, presumably because decltype(AType::Id)::MaxIdLen is a large value.
The compiler doesn't just store the string literal in the character array. It initialises the entire character array by using the string literal as a prefix, and padding the rest with zeros.

Returning to a specific place in a file after extraction of characters [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a question, after I loop on a file and extract several letters with a counter to know how many characters have been extracted how can I reposition my pointer to point back the first one extracted. Here is what I have tried so far:
int get_length(ifstream &inp,int &length){
int columns=0;
inp>>columns;
length++;
while(columns!=0)
{
inp>>columns;
length++;
}
if (!inp.good())
inp.clear();
inp.seekg(-length,std::ios::cur);
return length;
}
For some reason its not going back the same length, it's getting it wrong by one, I've tried adding to length by one then writing that seek function I don't know what's wrong here, I'm questing if I'm using the seek function incorrectly?
I think that the problem is this:
You are incrementing 'length' each time an integer value is read from the fstream 'inp'. Depending on on how many characters wide the integer representation is you will need to increment length by that amount. That and new-line chars and any other whitespace in the fstream.
If your test data contains:
10
11
12
13
Then by the time you read 13 you will have consumed 12 bytes of file data.
Your counter will have only incremented 4 times.
You could do this more easily and accurately by placing a call to
auto const position_start = inp.tellg();
at the start of your function and once you read the data you're interested in 'rewind' to the start position with a call to
inp.seekg(position_start, std::ios::beg);
'ifstream' is a specialisation of 'basic_ifstream', so 'ifstream::seekg()' takes an offset in bytes (chars). However, the formatted input (to an int) will advance the the current position by some number of bytes (0 or more) as it converts the input to an integer value. Use 'ifstream::tellg()' at the top of the function to get the current file position and another call to 'tellg()' before calling 'seekg()' to get the new file position. The difference in the two values will be 'length'.

How to test the end of an array of unsigned char? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How can we test the end of an array of unsigned char ? With a string char it's easy, I can just make a test like
while (str[i] != '\0')
or just
while (str[i])
But with an array of unsigned char that doesn't work and I don't really understand why. That's an example where I need help
BYTE* a = getB();
int i=0;
while(a[i]!=0)
{
printf("%C", a[i]);
i++;
}
Thanks
It is completely up to you.
That is, you define what the end of an array means.
Conventionally, sure, the end of a character array is a "null byte", signifiying the terminating position. There's no reason you can't do that with an array of unsigned char.
But, just like with char, this need not necessarily be the case. Maybe you signify the end of the array by counting its elements (specifying a size), or by declaring that some other character is the final one.
We cannot tell you what that is. Only the person who creates the data (as far as we're concerned here, that's you) can do so.
So, either consult the documentation for the library that gave you the array, or reach into your memory. :)
#eugenesh is right. You can't do do it. Either you need to have extra space at the end and add some kind of delimiter or keep a count of charactera

Convert std::string to char* debate [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In C++ 98, is this a legitimate method to cast from a string to a char *?
char * n = (char *) someString.c_str();
(In my original wording, the function above was recommended by a senior programmer)
Namely, is it a better method than:
s2 = (char *)alloca(s0.size() + 1);
memcpy(s2, s0.c_str(), s0.size() + 1);
(courtesy of convert string to char*)
If so, why?
Use Case:
I need to use a char*, but I don't need to alter the data after it is in the char*. I'm passing it to a display library.
I'm just looking for a short and sweet answer. Thanks!
Edit: I changed the wording to this question because it got down voted. I hope my rewording makes it a better question. I think the answers were interesting and insightful.
For the record: Anyone interested in this question, should look at all the responses. I could only pick one, but I found them all interesting.
string::c_str() returns a const pointer to a null-terminated C-style string that contains the same contents as the original string. In most common implementations, c_str() simply returns a pointer to the string's internal data if it is not empty, but that is not required by the C++ standard.
If you just need to read the content of the string and not modify it, there is no need to allocate a separate buffer, just use c_str() by itself. The returned char* will remain valid as long as the string is not altered, either by the =/+=/[] operator, or the insert() or erase() method, or an iterator, etc.
If you need to modify the string via the char* pointer, then you have to allocate a separate buffer, copy the string content into it, modify it as needed, and then copy the new content back to the string using its own methods.
Your senior programmer is wrong. Casting away const-ness like that at the very least is wrong (no guarantees that it points to the actual memory of the string for example), and yields undefined behavior if the underlying objects happen to be const.
The answer here depends on whether you need a mutable string or just to be able to read it.
If all you want to do with your char* is to look at the contents then, as the comments have pointed out, you need to assign it to a const char* (and drop the cast).
Your method works, but if all you need to do is read the string, there is no point in copying it to a new location.
If you need to modify the string, then your copy would be appropriate. However, you need to be aware that changes will not be reflected in the original string.
First off, memcpy does not allocate memory. It only copies things from one place to another.
In C++ the idiom, using memcpy is:
std::string my_string = "California Needs Rain!\n";
char * p_text_string = new char [my_string.length() + 1U];
memcpy(p_text_string,
my_string.c_str(),
my_string.length());
// Add the nul terminator
p_text_string[my_string.length()] = '\0';
Remember that the memory allocated needs to be 1 more than the length of the string because of the nul, '\0', terminator character that needs to be appended.
The std::string is not required to be nul terminated.

Simple General Questions about C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Ive moved from autoit and am now learning C++ and some problems keep coming up.
The first one is storing character input. The problem is that I have no idea how many characters are in that line of the file (if you are reading a file) or how many letters a user is going to type (in a console application).
What is the best way to approach this problem?? I have heard about the string class, but I want to avoid it becuase I dont know how it works and that leads to vunerabilities etc.
Secondly...
In C you can load shellcode into memory, create a function pointer, and execute that code.
Is there any mechanism for this in C++???
Thirdly...
How does the interpreter iterate through char arrays for string output??? (char array[3];) Does the compiler keep track of the size of the array, or does it just keep reading from memory until it hits that \0 thing???
Lastly...
If Char * are just pointers to data in memory, then why does:
char * title = "Program Title";
this work??? where is the string literal stored in memory?? how is it referenced???
Thankyou very much. I greatly appreciate your help.
-Hyperzap
Investing your time in learning std::string is well worth the effort, as it takes care of a lot of hassle for you. If you don't want to take advantage of the features in C++, then why use C++ and not just C?
You can use the same code for this as you would in C.
Yes, iostream-output of C-style strings outputs until terminating zero. Once again, if you use std::string you do not have to care about such details.
Correct me if I'm wrong, but I think title would be a const char[] stored on the stack.
Example:
const char* hello = "Hello\0World";
cout << hello; // Prints only "Hello", i.e. up to terminating zero (\0)
The reason this works:
const char* hello = "Hello world";
cout << hello;
is because hello is really "Hello world\0"; - in other words, the compiler inserts a terminating zero.
Note that std::string doesn't do any magic. It too reads until the terminating zero:
string hello = "Hello\0World\n";
cout << hello; // Still only gives "Hello"
char* title = "String Literal" works because the compiler preallocates a memory location to store your string literal, thus you then get back a pointer to this memory location.
In c++, an array for which you know the size at compile time (as in your example: char array[3] is a type in itself, so the compiler does keep track of the size. However, if you do not know the size (ie. char array[]), it is just a pointer to char. However, you should be using std::vector in c++ (better safety and performance).
I'm not too sure about your other two questions (didn't quite understand them)