Print sorted integer array element - c++

I'm trying to find the max and min values of an array. I have 'numArray', which is a string of comma separated numbers (e.g. - 3,5,1,6). I'm using a tokenizer to break them into individual ints and storing them in a separate array. I'm then sorting them and printing the 0th element, however 'nums[0]' prints the whole array in the exact order, as in 3,5,1,6.
I tried commenting the sorting part but I still got the whole array. What am I doing wrong?
I am a beginner in C++.
CString str = numArray;
int i=0;
int nums[50];
int nTokenPos = 0;
CString strToken = str.Tokenize(_T(","), nTokenPos);
while (!strToken.IsEmpty())
{
int x = atoi(strToken);
nums[i]=x;
strToken = str.Tokenize(_T(","), nTokenPos);
i++;
}
std::sort(nums,nums+50);
int min = nums[0];
CString someStr;
someStr.Format(_T("The minimum number is: %d"), min);
minMaxAvg.SetWindowTextA(str);

the error lies in the fact that your argument to minMaxAvg.SetWindowTextA is str when you probably meant to pass someStr, ie. you are passing the original string instead of your newly formatted one.
minMaxAvg.SetWindowTextA(str); /* <- this */
minMaxAvg.SetWindowTextA(someStr); /* <- should be this */

Related

strcpy to multi-dimensional array in C++

I've been having issues attempting to copy a word into a multi-dimensional array.
Here is the code I use to create the array:
char *word_buffer;
char *return_result[64];
int buffer_count = 0;
int word_start = 0;
int word_end = 0;
// Some extra, irreverent code.
for (int i = 0; i < length; i += 1) {
if (text[i] == delim) { // Delim is a value such as '\n'
word_end = i;
word_buffer = (char*) malloc(sizeof(char)*64);
strncpy(word_buffer, text + word_start, word_end - word_start); // Copy the word into word_buffer
strcpy(*(return_result + buffer_count), word_buffer);
word_start = i + 1;
}
}
I believe my issue lies with the last line. I attempt to give strcpy a pointer to the address of the 2d array where I want the result of word_buffer to be place. However, this results in a Segmentation Fault.
The goal is to have an array of words returned. I.E.
char *result[10] = { "foo", "bar", "x", "y", "z" };
But to have this done dynamically with code. My code to split the words is working fine. Though, I don't know how to place the value into a 2d array.
Edit: User SHR recommended I try replacing the strcpy line with return_array[buffer_count]=word_buffer;. This does partially work but it crashes after a random amount of values in the array every time. I don't really see how this could be due to high memory usage. Tracking the memory usage of the binary shows nothing out of the ordinary.

Segmentation Fault in C++ while using string vectors

My code is for an online coding practice site, I have been doing many of the challenges but I cannot seem to get around the segmentation fault error on this one.
The aim of the code is to find the longest length strings in a string vector (up to 10 strings long) and then to return a string vector containing just those longest strings in order.
I believe logically my code works, but I can't test it. I am still new to vectors so can't seem to properly understand other answers on here in relation to my issue.
vector<string> allLongestStrings(vector<string> inputArray) {
vector<string> longestStrings; // vector
int longest_size = longestStrings.size(); // int
int longestArrayCounter = 0; // int. For filling longestStrings whenever
// there is a long string
int longest_string = 0; // int. For recording the size of the longest string
for (int i = 0; i < inputArray.size(); i++) {
// Loop will:
//1. Measure size of string in input array
//2. if longest will change value of longest_string and clear longestStrings
//3. If the same length as longest_string will add it to longestStrings vector
//4. if it is shorter it will be ignored
if (inputArray[i].size() > longest_string) { // input vector
longest_string = inputArray[i].size(); // vector
longestStrings.clear(); //clearing the vector to only store longest string values
longestArrayCounter = 0; //reset counter for longestStrings
longestStrings[longestArrayCounter++] = inputArray[i];//puts new longest string from input into my vector
}
if (inputArray[i].size() == longest_string) {
longestStrings[longestArrayCounter++] =inputArray[i];// my vector and input vector
}
}
return longestStrings;
}
longestStrings.clear();
longestArrayCounter = 0;
longestStrings[longestArrayCounter++] = inputArray[i];
is bad because you are doing assignment to non-existent element.
Instead of the two
longestStrings[longestArrayCounter++] = inputArray[i];
you should do
longestStrings.push_back(inputArray[i]);
Then, std::vector will manage the size for you, so you don't have to manage longestArrayCounter by yourself. Use longestStrings.size() to obtain the size.

How can I find the size of a (* char) array inside of a function?

I understand how to find the size using a string type array:
char * shuffleStrings(string theStrings[])
{
int sz = 0;
while(!theStrings[sz].empty())
{
sz++;
}
sz--;
printf("sz is %d\n", sz);
char * shuffled = new char[sz];
return shuffled;
}
One of my questions in the above example also is, why do I have to decrement the size by 1 to find the true number of elements in the array?
So if the code looked like this:
char * shuffleStrings(char * theStrings[])
{
//how can I find the size??
//I tried this and got a weird continuous block of printing
int i = 0;
while(!theStrings)
{
theStrings++;
i++;
}
printf("sz is %d\n", i);
char * shuffled = new char[i];
return shuffled;
}
You should not decrement the counter to get the real size, in the fist snippet. if you have two element and one empty element, the loop will end with value , which is correct.
In the second snippet, you work on a pointer to a pointr. So the while-condition should be *theStrings (supposing that a NULL pointer ist the marker for the end of your table.
Note that in both cases, if the table would not hold the marker for the end of table, you'd risk to go out of bounds. Why not work with vector<string> ? Then you could get the size without any loop, and would not risk to go out of bounds
What you are seeing here is the "termination" character in the string or '\0'
You can see this better when you use a char* array instead of a string.
Here is an example of a size calculator that I have made.
int getSize(const char* s)
{
unsigned int i = 0;
char x = ' ';
while ((x = s[i++]) != '\0');
return i - 1;
}
As you can see, the char* is terminated with a '\0' character to indicate the end of the string. That is the character that you are counting in your algorithm and that is why you are getting the extra character.
As to your second question, seem to want to create a new array with size of all of the strings.
To do this, you could calculate the length of each string and then add them together to create a new array.

Why does my array element retrieval function return random value?

I am trying to make an own simple string implementation in C++. My implementation is not \0 delimited, but uses the first element in my character array (the data structure I have chosen to implement the string) as the length of the string.
In essence, I have this as my data structure: typedef char * arrayString; and I have got the following as the implementation of some primal string manipulating routines:
#include "stdafx.h"
#include <iostream>
#include "new_string.h"
// Our string implementation will store the
// length of the string in the first byte of
// the string.
int getLength(const arrayString &s1) {
return s1[0] - '0';
}
void append_str(arrayString &s, char c) {
int length = getLength(s); // get the length of our current string
length++; // account for the new character
arrayString newString = new char[length]; // create a new heap allocated string
newString[0] = length;
// fill the string with the old contents
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
// append the new character
newString[length - 1] = c;
delete[] s; // prevent a memory leak
s = newString;
}
void display(const arrayString &s1) {
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
}
void appendTest() {
arrayString a = new char[5];
a[0] = '5'; a[1] = 'f'; a[2] = 'o'; a[3] = 't'; a[4] = 'i';
append_str(a, 's');
display(a);
}
My issue is with the implementation of my function getLength(). I have tried to debug my program inside Visual Studio, and all seems nice and well in the beginning.
The first time getLength() is called, inside the append_str() function, it returns the correct value for the string length (5). When it get's called inside the display(), my own custom string displaying function (to prevent a bug with std::cout), it reads the value (6) correctly, but returns -42? What's going on?
NOTES
Ignore my comments in the code. It's purely educational and it's just me trying to see what level of commenting improves the code and what level reduces its quality.
In get_length(), I had to do first_element - '0' because otherwise, the function would return the ascii value of the arithmetic value inside. For instance, for decimal 6, it returned 54.
This is an educational endeavour, so if you see anything else worth commenting on, or fixing, by all means, let me know.
Since you are getting the length as return s1[0] - '0'; in getLength() you should set then length as newString[0] = length + '0'; instead of newString[0] = length;
As a side why are you storing the size of the string in the array? why not have some sort of integer member that you store the size in. A couple of bytes really isn't going to hurt and now you have a string that can be more than 256 characters long.
You are accessing your array out of bounds at couple of places.
In append_str
for (int counter = 1; counter < length; counter++) {
newString[counter] = s[counter];
}
In the example you presented, the starting string is "5foti" -- without the terminating null character. The maximum valid index is 4. In the above function, length has already been set to 6 and you are accessing s[5].
This can be fixed by changing the conditional in the for statement to counter < length-1;
And in display.
int max = getLength(s1);
for (int counter = 1; counter <= max; counter++) {
std::cout << s1[counter];
}
Here again, you are accessing the array out of bounds by using counter <= max in the loop.
This can be fixed by changing the conditional in the for statement to counter < max;
Here are some improvements, that should also cover your question:
Instead of a typedef, define a class for your string. The class should have an int for the length and a char* for the string data itself.
Use operator overloads in your class "string" so you can append them with + etc.
The - '0' gives me pain. You subtract the ASCII value of 42 from the length, but you do not add it as a character. Also, the length can be 127 at maximum, because char goes from -128 to +127. See point #1.
append_str changes the pointer of your object. That's very bad practice!
Ok, thank you everyone for helping me out.
The problem appeared to be inside the appendTest() function, where I was storing in the first element of the array the character code for the value I wanted to have as a size (i.e storing '5' instead of just 5). It seems that I didn't edit previous code that I had correctly, and that's what caused me the issues.
As an aside to what many of you are asking, why am I not using classes or better design, it's because I want to implement a basic string structure having many constraints, such as no classes, etc. I basically want to use only arrays, and the most I am affording myself is to make them dynamically allocated, i.e resizable.

Working with strcmp and string array

I'm trying to eliminate extra elements in the string array and I wrote the code below. There seems a problem with strcmp function and string arrays. Strcmp doesn't accept the string array elements that way. Can you help me fix that? array3 is string array. I'm coding in C++ and What I want to do is like there are multiple "apple"s or "banana"s in the string array. But I only need one "apple" or one "banana".
for(int l = 0; l<9999; l++)
{
for(int m=l+1;m<10000;m++)
if(!strcmp(array3[l],array3[m]))
{
array3[m]=array3[m+1];
}
}
strcmp returns 0 on equality, so if (strcmp(s1,s2))... means "if the strings are equal then do this...". Is that what you mean?
First of all, you can use operator== to compare strings of std::string type:
std::string a = "asd";
std::string b = "asd";
if(a == b)
{
//do something
}
Second, you have an error in your code, provided 10000 is the size of the array:
array3[m]=array3[m+1];
In this line you are accessing the m+1st element, with m being up to 10000. This means you will eventually try to access the 10001st element, and get out of array bonds.
Finally, your approach is wrong, and this way will not let you remove all the duplicate strings.
A better (but not the best) way to do it is this (pseudocode):
std::string array[];//initial array
std::string result[];//the array without duplicate elements
int resultSize = 0;//The number of unique elements.
bool isUnique = false;//A flag to indicate if the current element is unique.
for( int i = 0; i < array.size; i++ )
{
isUnique = true;//we assume that the element is unique
for( int j = 0; j < result.size; j++ )
{
if( array[i] == result[j] )
{
/*if the result array already contains such an element, it is, obviously,
not unique, and we have no interest in it.*/
isUnique = false;
break;
}
}
//Now, if the isUnique flag is true, which means we didn't find a match in the result array,
//we add the current element into the result array, and increase the count by one.
if( isUnique == true )
{
result[resultSize] = array[i];
resultSize++;
}
}
strcmp works on Cstrings only so if you wanna use it I suggest you alter it to the following: strcmp(array3[l].c_str(),array3[m].c_str()) which makes the strings C Strings.
Another option would be to simply compare them with the equality operator array3[l]==array3[m] this would tell you if the strings are equal or not.
Another way to do what you're trying to do is just to put the array in a set and iterate over it. Sets don't take more than one string of the same content!
References:
More about strcmp :http://en.cppreference.com/w/cpp/string/byte/strcmp
And moreabout c_str: http://en.cppreference.com/w/cpp/string/basic_string/c_str
Regarding String Comparison: http://en.cppreference.com/w/cpp/string/basic_string/compare
C++ Sets http://en.cppreference.com/w/cpp/container/set