Find longest Valid Parentheses(leetcode) [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
eg: if a string is ")(((())))))(", the answer should be 8.
I implement as follow:(learn from others)
int longestValidParentheses(string s) {
int len = s.length();
char* str = new char[len+1];
strcpy(str,s.c_str());
int maxlen=0;
stack<char*> stk;
char* cur = str;
while(*cur)
{
if(*cur=='(')
stk.push(cur);
else
{
if(!stk.empty() && *stk.top()=='(')
{
stk.pop();
maxlen = max(maxlen, cur-(stk.empty()?str-1:stk.top()));
}
else
stk.push(cur);
}
cur++;
}
return maxlen;
}
but I don't know why for this code, char* str = new char[len+1] but not char* str = new char[len]. Could anybody tell me why? If I use char* str = new char[len], an error will occur.

As you can tell from the comments, your problem is in the fact that you are mixing some constructs that are really C++ (like the string type) with functions and data types that are more typical of C (like char*, strcpy, etc). Bottom line: the length of a string is the number of characters in it; but the storage space needed is bigger than that, because a char* type of string has a terminating '\0' character to indicate "end of string". If you don't allocate space for that, then the '\0' that is appended at the end of the string copy operation will overwrite another memory location with possibly disastrous consequences.

You have no need to make a copy of the string in order to iterate it, since string comes with perfectly nice iterators that work exactly like char*:
The first 10 or so lines can be replaced by:
int maxlen = 0;
auto cur = s.begin(), end = s.end();
std::stack<decltype(cur)> stk;
while (cur != end) {
If you don't have C++11, use
std::string::iterator
in place of auto and decltype(cur).
One can also use indexes, or even make a char* into the string's own content:
cur = &s[0];
In no case is making a copy of the string and then leaking it a good idea.

int longestValidParentheses(string s){
int pos = 0;
int maxlen = 0;
while(pos != -1){
pos = substr(pos).find("(");
if(str.substr(pos).find(")") == -1) pos = -1;
maxlen += 2;
pos++;
}
return maxlen;
}
If you're using C++ might as well use the tools you have been given.

Floris already had given you the answer for your question. Let me just add one thing: you did not have to make a copy of that string. Note that you are allocating a buffer (new [len+1]) and you are strcpy'ing into it a value that you've got from s.c_str().
Check what is the c_str! The thing you are copying into your buffer is just an array of chars, char*, that you can completely appropriately use just like your new buffer. Try it:
int len = s.length();
char const* str = s.c_str();
and it should work just the same, without having to make a copy. (maybe you'll need to add some consts in a few places)

Related

Stumped on how to return reversed cstring

First and foremost, I'm new to cstrings and I have to use them for the assignment. I wish I didn't have to since they're a pain.
Anyway, the issue I'm having is with a function that accepts password, reverses the order, and passes it back to main. For whatever reason, I can't get it to populate the cstring tasked with holding the password. I've tried more than one way to get it working, but I've had no luck.
The function:
char* Reverse_Pass(char p_word[])
{
int last_let = strlen(p_word);
int rev_index = 0;
char* rev_pass = new char[last_let];
//cout << "\ntest 3";
rev_pass[0] = '\0';
//for (int i = last_let; i >= 0; i--)
while (p_word[last_let] != '\0')
{
rev_pass[rev_index] = p_word[last_let];
rev_index++;
last_let--;
}
return rev_pass;
}
I tried using a for loop for the process, but it throws a break point message when the result was sent to another function for verification of said password. This function at least allows the program to run without error. The issue I'm having is logical, but I can't see it.
There are a few issues here. First off is that strlen returns the length of the string not counting the null terminator. That means when you do
while (p_word[last_let] != '\0')
p_word[last_let] is '\0' since cstrign[strlen(cstring)] is the null terminator and the loop never executes. All of this though is still wrong. Really what you want to do is stop when last_let is less than 0.
This also affects rev_pass. You use
char* rev_pass = new char[last_let];
Which gives you enough storage for the string but not enough for the null terminator that all cstrings must have. What you need is
char* rev_pass = new char[last_let + 1];
Lastly, you never null terminate rev_pass. Since you know that it will be the last position that needs the null terminator you can simply use
rev_pass[last_let] = '\0';
After you allocate it.
All of those changes gives you
char* Reverse_Pass(char p_word[])
{
int last_let = strlen(p_word);
int rev_index = 0;
char* rev_pass = new char[last_let + 1];
rev_pass[last_let] = '\0';
while (last_let > 0)
{
rev_pass[rev_index++] = p_word[--last_let];
}
return rev_pass;
}
I would say three things here:
new char[last_let]; should be new char[last_let+1];, space for /0 not included in strlen returned value
rev_pass[0] = '\0'; should be `rev_pass[last_let] = '\0'; you want the string to be 0 terminated
the end loop condition is p_word[last_let] != '\0, but you are decreasing the value of last_let...so you are checking for a 0 byte before the begin of the string that is not guarantee in anyway. the strings are 0 terminated!
For the (3) I think if you flip the index usage in the loop (eg last_let for the reversed string and rev_index for the source should make the trick)
Happy coding, Ste

Optimize this function? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have written this code (Uses V8 library). I went through it a couple of times and this feels like it's the only way I can write something like this. The aim of the function is to replace the JavaScript .split() function; as when using that function with a limit doesn't include the last part of the array in the returning array. EG:
var str = "Test split string with limit";
var out = str.split(' ', 2);
The array out will contain: [Test, split]. I want it to contain: [Test, split, string with limit].
I know there are pure JS ways to do this however I find them hacky and possibly slower(?) than a single C++ bind call.
Here's my function:
/**
* Explodes a string but limits the tokens
* #param input
* #param delim
* #param limit
* #return
*/
void ASEngine::Engine::ASstrtok(const v8::FunctionCallbackInfo<v8::Value>& args)
{
Assert(3, args);
Isolate* isolate = args.GetIsolate();
/* Get args */
String::Utf8Value a1(args[0]);
String::Utf8Value a2(args[1]);
Local<Uint32> a3 = args[2]->ToUint32();
std::string input = std::string(*a1);
std::string delim = std::string(*a2);
unsigned int limit = a3->Int32Value();
unsigned int inputLen = input.length();
// Declare a temporary array to shove into the return later
std::vector<char*> tmp;
tmp.reserve(limit);
unsigned int delimlen = delim.length();
char* cp = (char*) malloc(inputLen);
char* cursor = cp + inputLen; // Cursor
char* cpp = (char*) cp; // Keep the start of the string
// Copy the haystack into a modifyable char ptr
memset(cp + inputLen, 0x00, 1);
memcpy(cp, input.c_str(), inputLen);
unsigned int arrayIndex = 0;
for(unsigned int i=0;i<limit;i++)
{
if((cursor = strstr(cp, delim.c_str())) == NULL)
{
cursor = (char*) cpp + inputLen;
break;
}
for(int j=0;j<delimlen;j++)
*(cursor+j) = 0x00;
tmp.push_back(cp);
cp = cursor + delimlen;
arrayIndex++;
}
if(*(cp) != '\0')
{
arrayIndex++;
tmp.push_back(cp);
}
Handle<Array> rtn = Array::New(args.GetIsolate(), arrayIndex);
/* Loop through the temporary array and assign
the variables to the V8 array */
for(unsigned int i=0;i<arrayIndex;i++)
{
rtn->Set(i, String::NewFromUtf8(
isolate, tmp[i], String::kNormalString, strlen(tmp[i])
));
}
/* Clean up memory */
delete cpp;
cp = NULL;
cpp = NULL;
cursor = NULL;
isolate = NULL;
/* Set the return */
args.GetReturnValue().Set(rtn);
}
If you are wondering: The variable cpp is there so I can delete the character pointer after I am done (As calling v8's String::NewFromUtf8() function copies the string) and I modify the cp pointer during the process of the function.
Before optimising, I would fix the code so that it is correct.
char* cp = (char*) malloc(inputLen);
...
/* Clean up memory */
delete cpp;
Whilst in some implementations, new and malloc do exactly the same thing, other implementations do not. So, if you allocate with malloc, use free to free the memory, not delete.
If you want to be clever about it, I expect:
tmp.reserve(limit+1);
will ensure that you have space for the remainder of the string without further allocation in the vector.
Since cursor isn't used after the loop, setting it inside the if that breaks the loop makes no sense.
if((cursor = strstr(cp, delim.c_str())) == NULL)
{
cursor = (char*) cpp + inputLen;
break;
}
You are using casts to (char *) in places that don't need it, for example:
char* cpp = (char*) cp; // Keep the start of the string
(cp is a char * already).
This:
memset(cp + inputLen, 0x00, 1);
is the same as:
cp[inputlen] = 0;
but unless the compiler inlines the memset, much faster.
Likewsie:
*(cursor+j) = 0x00;
can be written:
cursor[j] = 0;
However, assuming delimLen is greater than 1, you could get away with:
for(int j=0;j<delimlen;j++)
*(cursor+j) = 0x00;
converted to:
*cursor = 0;
Since your new cp value will skip to beyond delimlen anyway.
These serve absolutely no purpose:
cp = NULL;
cpp = NULL;
cursor = NULL;
isolate = NULL;
Unfortunately, I expect most of the time in your function won't be in any of the code I've commented on. But in the passing arguments back and forth between the calling JS library and the native C++ code. I'd be surprised if you gain anything over writing the same code in JS. (None of the above make much of a difference when it comes to speed, it's just correctness and "a small number of potentially wasted cycles if the compiler is rather daft").

Function isalnum(): unexpected results

For an assignment, I am using std::isalnum to determine if the input is a letter or a number. The point of the assignment is to create a "dictionary." It works well on small paragraphs, but does horrible on pages of text. Here is the code snippet I am using.
custom::String string;
std::cin >> string;
custom::String original = string;
size_t size = string.Size();
char j;
size_t i = 0;
size_t beg = 0;
while( i < size)
{
j = string[i];
if(!!std::isalnum(static_cast<unsignedchar>(j)))
{
--size;
}
if( std::isalnum( j ) )
{
string[i-beg] = tolower(j);
}
++i;
}//end while
string.SetSize(size - beg, '\0');
The code presented as I write this, does not make sense as a whole.
However, the calls to isalnum, as shown, would only work for plain ASCII, because
the C character classification functions require non-negative argument, or else EOF as argument, and
in order to work for international characters,
the encoding must be single-byte per character, and
setlocale should have been called prior to using the functions.
Regarding the first of these three points, you can wrap std::isalnum like this:
using Byte = unsigned char;
auto is_alphanumeric( char const ch )
-> bool
{ return !!std::isalnum( static_cast<Byte>( ch ) ); }
where the !! is just to silence a sillywarning from Visual C++ (warning about "performance", of all things).
Disclaimer: code untouched by compiler's hands.
Addendum: if you don't have a C++11 compiler, but only C++03,
typedef unsigned char Byte;
bool is_alphanumeric( char const ch )
{
return !!std::isalnum( static_cast<Byte>( ch ) );
}
As Bjarne remarked, C++11 feels like a whole new language! ;-)
I was able to create a solution to the problem. I noticed that isalnum did take care of some non alpha-numerics, but not all the time. Since the code above is part of a function, I called it multiple times with refined results given each time. I then came up with a do while loop that stores the string's size, calls the function, stores the new size, and compares them. If they are not the same it means that there is a chance that it needs to be called again. If they are the same, then the string has been fully cleaned. I am guessing that the reason isalnum was not working well was because I was reading in several chapters of a book into the string. Here is my code:
custom::string abc;
std::cin >> abc;
size_t first = 0;
size_t second = 0;
//clean the word
do{
first = abc.Size();
Cleanup(abc);
second = abc.Size();
}while(first != second);

copy char* to std::string at the specified pos not allocating new objects

Let me ask my question by code:
char* apples = "apples";
std::string str("I like .....");
// need to copy apples to str to have "I like apples", without creating new objects
There is assign function but unfortunately it seems is not possible to provide std::string offset.
I do not want to allocate new object as this is low-latency and frequently part of code.
upd by mistake i've put 5 dots above but I meant 6 dots to fit "apples" perfectly :) Of course if string capacity is not enought some objects have to be created. In my question I assume that string capacity is enough.
You can use std::copy algorithm http://www.cplusplus.com/reference/algorithm/copy/
std::copy(apples, apples + sz, str.begin() + offset);
Why not use std::string::replace?
Even assign will copy the content of whatever you pass to it. You will not be able to do what you try to. A string holds a pointer to a continuous block of characters in the memory. You can not just glue arbitrary things to it.
The answer of using the std::copy() algorithm is the best one AFAIK. You could also use plain old C (you understand, it is not actually C, C style would be a better name) to achieve the same thing:
char* apples = "apples";
std::string str("I like .....");
char * ptr = apples;
while( *ptr != 0 ) {
str.push_back( *ptr );
++ptr;
}
As you can see, there is no temporary object created here, but... Does that mean there are no allocations in the process? Indeed they are.
A std::string is basically a vector of chars. The string has a capacity() method that returns how many extra chars can be appended without triggering another allocation (which can involve a reallocation, thus copying the whole vector). The best you can do in order to avoid allocations is to ensure that the string will have enough space for all characters to insert.
char* apples = "apples";
std::string str("I like .....");
str.reserve( str.length() + strlen( apples ) );
char * ptr = apples;
while( *ptr != 0 ) {
str.push_back( *ptr );
++ptr;
}
This way you can ensure that there will be one allocation only in the std::string: the one triggered with reserve().
Hope this helps.
char * apples = "apples";
string something = "I like ....";
for (int i = 0; i < something.length() - 1; i++)
{
if (something.find('.'))
something.pop_back();
}
something.resize(something.length() + 1);
for (int i = 0; i < strlen(apples); i++)
something.push_back(apples[i]);
cout << something <<endl;

C++ exam on string class implementation

I just took an exam where I was asked the following:
Write the function body of each of the methods GenStrLen, InsertChar and StrReverse for the given code below. You must take into consideration the following;
How strings are constructed in C++
The string must not overflow
Insertion of character increases its length by 1
An empty string is indicated by StrLen = 0
class Strings {
private:
char str[80];
int StrLen;
public:
// Constructor
Strings() {
StrLen=0;
};
// A function for returning the length of the string 'str'
int GetStrLen(void) {
};
// A function to inser a character 'ch' at the end of the string 'str'
void InsertChar(char ch) {
};
// A function to reverse the content of the string 'str'
void StrReverse(void) {
};
};
The answer I gave was something like this (see bellow). My one of problem is that used many extra variables and that makes me believe am not doing it the best possible way, and the other thing is that is not working....
class Strings {
private:
char str[80];
int StrLen;
int index; // *** Had to add this ***
public:
Strings(){
StrLen=0;
}
int GetStrLen(void){
for (int i=0 ; str[i]!='\0' ; i++)
index++;
return index; // *** Here am getting a weird value, something like 1829584505306 ***
}
void InsertChar(char ch){
str[index] = ch; // *** Not sure if this is correct cuz I was not given int index ***
}
void StrRevrse(void){
GetStrLen();
char revStr[index+1];
for (int i=0 ; str[i]!='\0' ; i++){
for (int r=index ; r>0 ; r--)
revStr[r] = str[i];
}
}
};
I would appreciate if anyone could explain me roughly what is the best way to have answered the question and why. Also how come my professor closes each class function like " }; ", I thought that was only used for ending classes and constructors only.
Thanks a lot for your help.
First, the trivial }; question is just a matter of style. I do that too when I put function bodies inside class declarations. In that case the ; is just an empty statement and doesn't change the meaning of the program. It can be left out of the end of the functions (but not the end of the class).
Here's some major problems with what you wrote:
You never initialize the contents of str. It's not guaranteed to start out with \0 bytes.
You never initialize index, you only set it within GetStrLen. It could have value -19281281 when the program starts. What if someone calls InsertChar before they call GetStrLen?
You never update index in InsertChar. What if someone calls InsertChar twice in a row?
In StrReverse, you create a reversed string called revStr, but then you never do anything with it. The string in str stays the same afterwords.
The confusing part to me is why you created a new variable called index, presumably to track the index of one-past-the-last character the string, when there was already a variable called StrLen for this purpose, which you totally ignored. The index of of one-past-the-last character is the length of the string, so you should just have kept the length of the string up to date, and used that, e.g.
int GetStrLen(void){
return StrLen;
}
void InsertChar(char ch){
if (StrLen < 80) {
str[StrLen] = ch;
StrLen = StrLen + 1; // Update the length of the string
} else {
// Do not allow the string to overflow. Normally, you would throw an exception here
// but if you don't know what that is, you instructor was probably just expecting
// you to return without trying to insert the character.
throw std::overflow_error();
}
}
Your algorithm for string reversal, however, is just completely wrong. Think through what that code says (assuming index is initialized and updated correctly elsewhere). It says "for every character in str, overwrite the entirety of revStr, backwards, with this character". If str started out as "Hello World", revStr would end up as "ddddddddddd", since d is the last character in str.
What you should do is something like this:
void StrReverse() {
char revStr[80];
for (int i = 0; i < StrLen; ++i) {
revStr[(StrLen - 1) - i] = str[i];
}
}
Take note of how that works. Say that StrLen = 10. Then we're copying position 0 of str into position 9 of revStr, and then position 1 of str into position 9 of revStr, etc, etc, until we copy position StrLen - 1 of str into position 0 of revStr.
But then you've got a reversed string in revStr and you're still missing the part where you put that back into str, so the complete method would look like
void StrReverse() {
char revStr[80];
for (int i = 0; i < StrLen; ++i) {
revStr[(StrLen - 1) - i] = str[i];
}
for (int i = 0; i < StrLen; ++i) {
str[i] = revStr[i];
}
}
And there are cleverer ways to do this where you don't have to have a temporary string revStr, but the above is perfectly functional and would be a correct answer to the problem.
By the way, you really don't need to worry about NULL bytes (\0s) at all in this code. The fact that you are (or at least you should be) tracking the length of the string with the StrLen variable makes the end sentinel unnecessary since using StrLen you already know the point beyond which the contents of str should be ignored.
int GetStrLen(void){
for (int i=0 ; str[i]!='\0' ; i++)
index++;
return index; // *** Here am getting a weird value, something like 1829584505306 ***
}
You are getting a weird value because you never initialized index, you just started incrementing it.
Your GetStrLen() function doesn't work because the str array is uninitialized. It probably doesn't contain any zero elements.
You don't need the index member. Just use StrLen to keep track of the current string length.
There are lots of interesting lessons to learn by this exam question. Firstly the examiner is does not appear to a fluent C++ programmer themselves! You might want to look at the style of the code, including whether the variables and method names are meaningful as well as some of the other comments you've been given about usage of (void), const, etc... Do the method names really need "Str" in them? We are operating with a "Strings" class, after all!
For "How strings are constructed in C++", well (like in C) these are null-terminated and don't store the length with them, like Pascal (and this class) does. [#Gustavo, strlen() will not work here, since the string is not a null-terminated one.] In the "real world" we'd use the std::string class.
"The string must not overflow", but how does the user of the class know if they try to overflow the string. #Tyler's suggestion of throwing a std::overflow_exception (perhaps with a message) would work, but if you are writing your own string class (purely as an exercise, you're very unlikely to need to do so in real life) then you should probably provide your own exception class.
"Insertion of character increases its length by 1", this implies that GetStrLen() doesn't calculate the length of the string, but purely returns the value of StrLen initialised at construction and updated with insertion.
You might also want to think about how you're going to test your class. For illustrative purposes, I added a Print() method so that you can look at the contents of the class, but you should probably take a look at something like Cpp Unit Lite.
For what it's worth, I'm including my own implementation. Unlike the other implementations so far, I have chosen to use raw-pointers in the reverse function and its swap helper. I have presumed that using things like std::swap and std::reverse are outside the scope of this examination, but you will want to familiarise yourself with the Standard Library so that you can get on and program without re-inventing wheels.
#include <iostream>
void swap_chars(char* left, char* right) {
char temp = *left;
*left = *right;
*right = temp;
}
class Strings {
private:
char m_buffer[80];
int m_length;
public:
// Constructor
Strings()
:m_length(0)
{
}
// A function for returning the length of the string 'm_buffer'
int GetLength() const {
return m_length;
}
// A function to inser a character 'ch' at the end of the string 'm_buffer'
void InsertChar(char ch) {
if (m_length < sizeof m_buffer) {
m_buffer[m_length++] = ch;
}
}
// A function to reverse the content of the string 'm_buffer'
void Reverse() {
char* left = &m_buffer[0];
char* right = &m_buffer[m_length - 1];
for (; left < right; ++left, --right) {
swap_chars(left, right);
}
}
void Print() const {
for (int index = 0; index < m_length; ++index) {
std::cout << m_buffer[index];
}
std::cout << std::endl;
}
};
int main(int, char**) {
Strings test_string;
char test[] = "This is a test string!This is a test string!This is a test string!This is a test string!\000";
for (char* c = test; *c; ++c) {
test_string.InsertChar(*c);
}
test_string.Print();
test_string.Reverse();
test_string.Print();
// The output of this program should look like this...
// This is a test string!This is a test string!This is a test string!This is a test
// tset a si sihT!gnirts tset a si sihT!gnirts tset a si sihT!gnirts tset a si sihT
return 0;
}
Good luck with the rest of your studies!
void InsertChar(char ch){
str[index] = ch; // *** Not sure if this is correct cuz I was not given int index ***
}
This should be something more like
str[strlen-1]=ch; //overwrite the null with ch
str[strlen]='\0'; //re-add the null
strlen++;
Your teacher gave you very good hints on the question, read it again and try answering yourself. Here's my untested solution:
class Strings {
private:
char str[80];
int StrLen;
public:
// Constructor
Strings() {
StrLen=0;
str[0]=0;
};
// A function for returning the length of the string 'str'
int GetStrLen(void) {
return StrLen;
};
// A function to inser a character 'ch' at the end of the string 'str'
void InsertChar(char ch) {
if(StrLen < 80)
str[StrLen++]=ch;
};
// A function to reverse the content of the string 'str'
void StrReverse(void) {
for(int i=0; i<StrLen / 2; ++i) {
char aux = str[i];
str[i] = str[StrLen - i - 1];
str[StrLen - i - 1] = aux;
}
};
};
When you init the char array, you should set its first element to 0, and the same for index. Thus you get a weird length in GetStrLen since it is up to the gods when you find the 0 you are looking for.
[Update] In C/C++ if you do not explicitly initialize your variables, you usually get them filled with random garbage (the content of the raw memory allocated to them). There are some exceptions to this rule, but the best practice is to always initialize your variables explicitly. [/Update]
In InsertChar, you should (after checking for overflow) use StrLen to index the array (as the comment specifies "inser a character 'ch' at the end of the string 'str'"), then set the new terminating 0 character and increment StrLen.
You don't need index as a member data. You can have it a local variable if you so please in GetStrLen(): just declare it there rather than in the class body. The reason you get a weird value when you return index is because you never initialized it. To fix that, initialize index to zero in GetStrLen().
But there's a better way to do things: when you insert a character via InsertChar() increment the value of StrLen, so that GetStrLen() need only return that value. This will make GetStrLen() much faster: it will run in constant time (the same performance regardless of the length of string).
In InsertChar() you can use StrLen as you index rather than index, which we already determined is redundant. But remember that you must make sure the string terminates with a '\0' value. Also remember to maintain StrLen by incrementing it to make GetStrLen()'s life easier. In addition, you must take the extra step in InsertChar() to avoid a buffer overflow. This happens when the user inserts a character to the string when the length of the string is alreay 79 characters. (Yes, 79: you must spend one character on the terminating null).
I don't see an instruction as to how to behave when that happens, so it must be up to your good judgment call. If the user tries to add the 80th character you might ignore the request and return, or you might set an error flag -- it's up to you.
In your StrReverse() function you have a few mistakes. First, you call GetStrLen() but ignore its return value. Then why call it? Second, you're creating a temporary string and work on that, rather than on the string member of the class. So your function doesn't change the string member, when it should in fact reverse it. And last, you could reverse the string faster by iterating through half of it only.
Work on the member data string. To reverse a string you can swap the first element (character) of the string with its last (not the terminating null, the character just before that!), the second element with the second-to-last and so on. You're done when you arrive at the middle of the string. Don't forget that the string must terminate with a '\0' character.
While you were solving the exam it would also be a good opportunity to teach your instructor a think or two about C++: we don't say f(void) because that belongs to the old days of C89. In C++ we say f(). We also strive in C++ to use class initializer lists whenever we can. Also remind your instructor how important const-correctness is: when a function shouldn't change the object is should be marked as such. int GetStrLen(void) should be int GetStrLen() const.
You don't need to figure out the length. You already know it it is strLen. Also there was nothing in the original question to indicate that the buffer should contain a null terminated string.
int GetStrLen(void){
return strLen;
}
Just using an assertion here but another option is to throw an exception.
void InsertChar(char ch){
assert(strLen < 80);
str[strLen++] = ch;
}
Reversing the string is just a matter of swapping the elements in the str buffer.
void StrRevrse(void){
int n = strLen >> 1;
for (int i = 0; i < n; i++) {
char c = str[i];
str[i] = str[strLen - i];
str[strLen - i] = c;
}
}
I would use StrLen to track the length of the string. Since the length also indicates the end of the string, we can use that for inserting:
int GetStrLen(void) {
return StrLen;
}
int InsertChar(char ch)
{
if (strLen < sizeof(str))
{
str[StrLen] = ch;
++strLen;
}
}
void StrReverse(void) {
for (int n = 0; n < StrLen / 2; ++n)
{
char tmp = str[n];
str[n] = str[StrLen - n - 1];
str[StrLen - n - 1] = tmp;
}
}
first of all why on you use String.h for the string length?
strlen(char[] array) returns the Lenght or any char array to a int.
Your function return a werid value because you never initialize index, and the array has zero values, first initilize then execute your method.