Command line with sorted numbers

So I have a program that uses command line arguments to generate numbers and determine what should happen to the numbers (i.e sort in ascending or descending order, leave as random or make them all equal). The first argument is a.out, the second, n, is how many numbers you want and the third is the type (from 1-4 to determine what should happen to the numbers). The fourth value is optional. The problem is that I'm getting garbage no matter what I do and I can't spot the problem. Any suggestions?

First is .h file, 2nd cpp file, the 3rd is implementation file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  #ifndef GEN_H
#define GEN_H

const int
ASCENDING = 1,
DESCENDING = 2,
EQUAL = 3,
RANDOM = 4;

// type is one of the above constants,
void gen(int *arr, int n, int type, int val); // fill is the value used for EQUAL; or the range for RANDOM
void gen(int *arr, int n, int type); // for ASCENDING and DESCENDING; always start/end at 1

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdlib>
#include "gen.h"
using namespace std;

void gen(int *arr, int n, int type, int val){
    int s[n];
    if (type == 'R' && val){
        for (int i = 0; i < n; i++)
            s[i] = rand() % val;
    }
    else if (type == 'R' && !val){
        for (int i = 0; i < n; i++)
            s[i] = rand();
    }
    else if (type == 'E' && val){
        for (int i = 0; i < n; i++)
             s[i] = val;
    }
    else if (type == 'E' && !val){
        int r;
        r = rand();
        for (int i = 0; i < n; i++)
            s[i] = r;
    }
    
}
void gen(int *arr, int n, int type){
    int s[n];
    if (type == 'A'){
        for (int i = 0; i < n; i++){
            s[i] = rand();
        }
        for (int last = 0; last < n; last++){
            for (int i = 0; i < last; i++){
                if (s[i] > s[i+1]){
                    swap(s[i], s[i+1]);
                    }
                }
            }
        
    }
    if (type == 'D'){
        for (int i = 0; i < n; i++){
            s[i] = rand();
        }
        for (int last = 0; last < n; last++){
            for (int i = 0; i < last; i++){
                if (s[i] < s[i+1]){
                    swap(s[i], s[i+1]);
                }
            }
        }
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <sstream>
#include <cstdlib>
#include "gen.h"
using namespace std;

int main(int argc, char *argv[]) {
	if (argc < 3 || argc > 4) {
		cerr << argv[0] << ": <how_many> <type> {<range/fill>}" << endl;
		exit(1);
	}
    
	istringstream iss;
	iss.str(argv[1]);
	int n;
	iss >> n;
	cerr << "n: " << n << endl;
    
	string type = (string)argv[2];
	cerr << "type: " << type << endl;
    
	int value = 0;
	bool hasValue = false;
	if (argc == 4) {
		hasValue = true;
		iss.str(argv[3]);
		iss.clear();
		iss >> value;
		cerr << "value: " << value << endl;
	}
    
	int arr[n];
    
	switch (type[0]) {
		case 'A': gen(arr, n, ASCENDING); break;
		case 'D': gen(arr, n, DESCENDING); break;
		case 'E':   if (hasValue)
                        gen(arr, n, EQUAL, value);
                    else
                        gen(arr, n, EQUAL);
                    break;
		case 'R':   if (hasValue)
                        gen(arr, n, RANDOM, value);
                    else
                        gen(arr, n, RANDOM);
                    break;
	}
    
	for (int i = 0; i < n; i++)
		cout << arr[i] << " ";
	cout << endl;
	
	return 0;
}
This should not work at all: int arr[n]; n is not a constexpr.

Use the standard library.
Something like this (if the implementation does not have std::stoi(), use a string stream instead):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>

int main( int argc, char* argv[] )
{
    std::srand( std::time(nullptr) ) ;
    
    if( argc == 3 || argc == 4 )
    {
        try
        {
            // http://en.cppreference.com/w/cpp/string/basic_string/stol
            const int how_many = std::stoi( argv[1] ) ;
            std::cout << "how many: " << how_many << ' ' ;
            
            if( how_many > 0 )
            {
                const char type = std::toupper( argv[2][0] ) ;
                std::cout << "type: '" << type << "' " ;
                
                const std::string valid_types = "ADRE" ;
                if( valid_types.find(type) != std::string::npos )
                {
                    std::vector<int> array( how_many ) ;
                    
                    if( type == 'E' )
                    {
                        const int value = argc == 4 ? std::stoi( argv[3] ) : std::rand() ;
                        std::cout << "value: " << value  ; 
                        
                        // http://en.cppreference.com/w/cpp/algorithm/fill_n
                        std::fill_n( array.begin(), how_many, value ) ;
                    }
                         // http://en.cppreference.com/w/cpp/algorithm/generate_n 
                    else std::generate_n( array.begin(), how_many, std::rand ) ;
                    
                    if( type == 'A' ) std::sort( array.begin(), array.end() ) ;
                    else if( type == 'D' ) std::sort( array.rbegin(), array.rend() ) ;
                    
                    std::cout << "\ngenerated sequence: " ;
                    for( int v : array ) std::cout << v << ' ' ;
                    std::cout << "\n-------------\n" ;
                    return 0 ;
                }
            }
        }
        
        catch( const std::exception& ) { std::cerr << "error in command line args\n" ; }
        return 1 ;
    }
    
    std::cerr << "error in command line args\n" ;
}

clang++ -std=c++11 -stdlib=libc++ -O2 -Wall -Wextra -pedantic-errors main.cpp -lsupc++
./a.out 8 ASCENDING
./a.out 5 DESCENDING
./a.out 7 RANDOM
./a.out 6 EQUAL
./a.out 12 EQUAL 12345
how many: 8 type: 'A' 
generated sequence: 19879023 140266761 685975674 1079753803 1772086432 2037704393 2068879258 2075170513 
-------------
how many: 5 type: 'D' 
generated sequence: 2075170513 2068879258 685975674 140266761 19879023 
-------------
how many: 7 type: 'R' 
generated sequence: 2075170513 2068879258 685975674 140266761 19879023 1079753803 2037704393 
-------------
how many: 6 type: 'E' value: 2075170513
generated sequence: 2075170513 2075170513 2075170513 2075170513 2075170513 2075170513 
-------------
how many: 12 type: 'E' value: 12345
generated sequence: 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 
-------------

http://coliru.stacked-crooked.com/a/cdbd51c1d13a7e32
That is some great code! However I can't apply it to my program. The .h file and implementation were coded before and I had to write the cpp file.
Could you go into more detail about why int arr[n]; doesn't work. When I analyze it in xcode it just says "function call argument is an uninitialized value"
int arr[n]; is illegal because you're attempting to create an array of non-const size on the stack. You'd use dynamic memory for this.
So I dynamically allocated int arr[n] so it looks like this:
1
2
int *arr;
arr = new int [n];

Now instead of getting garbage I get all zeros. Am I not allocating it right?
Line 2 will allocate an uninitialized array.
What were you exepecting it to contain?

Or do you mean the cout at line 50 is displaying all zeroes?

Edit:
In looking at your gen functions, I don't see anywhere that you're modifying the passed array. You put random numbers into s, but the contents of s are lost when s goes out of scope upon exit of gen.

Last edited on
the cout at line 50 is all zeros. The function for generating numbers is the second file from the first post.
Please see my corrected post above.
I tried changing all the s's int arr but that didn't work. I see what you are saying. I need a way to access s. How would I go about doing that?
Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void gen(int *s, int n, int type, int val)
{  if (type == 'R' && val){
        for (int i = 0; i < n; i++)
            s[i] = rand() % val;
    }
    else if (type == 'R' && !val){
        for (int i = 0; i < n; i++)
            s[i] = rand();
    }
    else if (type == 'E' && val){
        for (int i = 0; i < n; i++)
             s[i] = val;
    }
    else if (type == 'E' && !val){
        int r;
        r = rand();
        for (int i = 0; i < n; i++)
            s[i] = r;
    }    
}
I tried it and it still didn't work. I got garbage.
Last edited on
So I've been trying everything and I still can't get it to work. I either get garbage or all zeros. It seems like the problem is that I can't access the info that is being put into the arrays in the functions. How can I access that info?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <functional>

void gen( int array[], std::size_t n, int /*type*/, int value )
{ 
    std::cout << "value: " << value << ' ' ;
    std::fill_n( array, n, value ) ; 
}

void gen( int array[], std::size_t n, int type )
{ 
    if( type == 'E' )
    {
        std::cout << "random " ;
        gen( array, n, type, std::rand() ) ;
    }
    
    else
    {
        std::generate_n( array, n, std::rand ) ;
        
        if( type == 'A' ) std::sort( array, array+n ) ;
        
        else if( type == 'D' ) std::sort( array, array+n, std::greater<int>() ) ;
    }
}


int main( int argc, char* argv[] )
{
    std::srand( std::time(nullptr) ) ;
    
    if( argc == 3 || argc == 4 )
    {
        try
        {
            // http://en.cppreference.com/w/cpp/string/basic_string/stol
            const int how_many = std::stoi( argv[1] ) ;
            std::cout << "how many: " << how_many << ' ' ;
            
            if( how_many > 0 )
            {
                const char type = std::toupper( argv[2][0] ) ;
                std::cout << "type: '" << type << "' " ;
                
                const std::string valid_types = "ADRE" ;
                if( valid_types.find(type) != std::string::npos )
                {
                    std::vector<int> array( how_many ) ;
                    
                    if( type == 'E' && argc == 4 ) gen( &array.front(), array.size(), type, std::stoi( argv[3] ) ) ;
                    else gen( &array.front(), array.size(), type ) ;

                    std::cout << "\ngenerated sequence: " ;
                    for( int v : array ) std::cout << v << ' ' ;
                    std::cout << "\n-------------\n" ;
                    return 0 ;
                }
            }
        }
        
        catch( const std::exception& ) { std::cerr << "error in command line args\n" ; }
        return 1 ;
    }
    
    std::cerr << "error in command line args\n" ;
}

clang++ -std=c++11 -stdlib=libc++ -O2 -Wall -Wextra -pedantic-errors main.cpp -lsupc++
./a.out 8 ASCENDING
./a.out 5 DESCENDING
./a.out 7 RANDOM
./a.out 6 EQUAL
./a.out 12 EQUAL 12345
how many: 8 type: 'A' 
generated sequence: 149823565 175243941 348746003 594564399 973772049 1280724190 2082808166 2089753942 
-------------
how many: 5 type: 'D' 
generated sequence: 2089753942 2082808166 973772049 348746003 149823565 
-------------
how many: 7 type: 'R' 
generated sequence: 973772049 2082808166 348746003 2089753942 149823565 1280724190 175243941 
-------------
how many: 6 type: 'E' random value: 973772049 
generated sequence: 973772049 973772049 973772049 973772049 973772049 973772049 
-------------
how many: 12 type: 'E' value: 12345 
generated sequence: 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 
-------------

http://coliru.stacked-crooked.com/a/cad866f5c7a86caa
Again, the code looks good but I can't use it. I must use the the .h file and implementation file that I was given in the first place.
> I must use the the .h file and implementation file that I was given in the first place.

You can't use the implementation file that you were given in the first place - it is not well-formed C++ code.

Even if it were C99, the two gen() functions as implemented are meaningless - they do not modify the array passed to them and do not return anything.
Their only observable side effect is some number of calls to std::rand().
Okay, so this is embarrassing, I was calling the demo file the implementation file. Big mistake on my part. What I mean this time is that the .h file and demo file are given to me. JLBorges, I took your comments to heart about the not well formed c++ code so I started over and took some queues from your previous submissions. Again it still doesn't work. It could be that I'm not understanding pointers, but I have read the reference article and tried all the possible ways of doing it. So, this is what I have:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include "gen.h"
using namespace std;

void gen(int *arr, int n, int type, int val){
    while (val && ((type == 'D') || (type == 'E'))){
        for (int i = 0; i < n; i++){
                arr[i] = rand() % val;
            }
        if (type == 'E')
            for (int i = 0; i < n; i++){ arr[i] = val; }
        }
    while (!val && ((type == 'D') || (type == 'E'))){
        for (int i = 0; i < n; i++){
            arr[i] = rand();
        }
        if (type == 'E')
            for (int i = 0; i < n; i++){ arr[i] = arr[0]; }
    }
}

void gen(int *arr, int n, int type){
    if ((type == 'A') || (type == 'D'))
        for (int i = 0; i < n; i++){
            arr[i] = rand();
        }
    sort (arr, arr+n);
    if (type == 'D'){ reverse(arr, arr+n); }
}
Last edited on
In the gen() functions:

Step 1.

If the type is 'A', 'D' or 'R' fill the array with differerent random values

else if the type is 'E' fill it with the same value (value if it is given, a random value otherwise).


Step 2.

If the type is 'A' sort the array in ascending order.
If the type is 'D' sort the array in descending order.
I got it! the problem was that in the gen() functions type are the int values not the char values. Once I switch those out, it all works.
Topic archived. No new replies allowed.