-4
#include <iostream>
#include <fstream>
#include <cmath>
#include <bits/stdc++.h>
#include <string.h>
#define MAX_LEN 9999

using namespace std;

void printDNAarray(const char * dnaArray, int length){
    cout<<"Printing DNA Array of length: "<<length<<endl;
    for(int i=0; i<length; i++)
        cout<<dnaArray[i];
    cout<<endl;
}

char * processDNAString(string line){
    char * arrayToSort = new char[line.length()];
    for(int i=0; i< line.length();i++)
        arrayToSort[i] = line[i];
    return arrayToSort;
}

/*
 *  Selection Sorting Algorithm
 */
void selectionSort (char arrayToSort[][MAX_LEN], int n)
{
    int i,j,min_idx;
    char minStr[MAX_LEN];
    for (i=0;i<n-1;i++)
    {
        int min_idx=i;
        strcpy(minStr,arrayToSort[i]);
        for(j=i+1;j<n;j++)
        {
            if (strcmp(minStr, arrayToSort[j])>0)
            {
                strcpy(minStr,arrayToSort[j]);
                min_idx=j;
            }
        }   
        if (min_idx !=i)
        {
            char temp[MAX_LEN];
            strcpy (temp, arrayToSort[i]);
            strcpy(arrayToSort[i],arrayToSort[min_idx]);
            strcpy(arrayToSort[min_idx],temp);
        }
    }
}




int main(int argc, char * argv[]) 
{
    ifstream fin;
    string line;
    std::string cur_dir(argv[0]);
    
    int pos = cur_dir.find_last_of("/\\");
    string path = cur_dir.substr(0, pos);
    std::cout << "path: " << cur_dir.substr(0, pos) << std::endl;
    std::cout << "Exec file: " << cur_dir.substr(pos+1) << std::endl;
    string filename = path + "/rosalind_dna.txt";
    cout << "Opening dataset file: "<<filename<< endl;
    fin.open(filename);

    if(!fin){
        cerr << "Unable to open rosalind_dna.txt file..."<<endl;
        cerr << "Review your current working directory!!"<<endl;
        exit(1);
    }

    while(fin){
        getline(fin,line);
        cout << line <<endl;
        break;
    }
    cout<<endl;

    char * dnaArray = processDNAString(line);
    printDNAarray(dnaArray, line.length());
    cout<<"Sorting DNA Array ..."<<endl;

    //Implementation
    selectionSort(dnaArray,line.length());
    printDNAarray(dnaArray, line.length());
    
    
    
fin.close();
    return 0;
}

I need help, it is to be a selectionsort algorithm but I can't make it work because these errors:

main.cpp:96:19: error: cannot convert ‘char*’ to ‘char (*)[9999]’
   96 |     selectionSort(dnaArray,line.length());
      |                   ^~~~~~~~
      |                   |
      |                   char*
main.cpp:35:26: note:   initializing argument 1 of ‘void selectionSort(char (*)[9999], int)’
   35 | void selectionSort (char arrayToSort[][MAX_LEN], int n)
      |                     ~~~~~^~~~~~~~~~~~~~~~~~~~~~ ~~~~~^~~~~~~~~~~~~~~~~~~~~~
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
ChiriG
  • 1
  • 1
  • 3
    You declare parameter "arrayToSort" like this: `void selectionSort (char arrayToSort[][MAX_LEN], int n)`. But you pass variable `char * dnaArray`! SUGGESTION: Since you're coding this in C++, why not *FORGET* about "char * " altogether. And use something like std::vector instead? – paulsm4 May 17 '22 at 02:39

2 Answers2

1

The problem(mentioned error) is that the first parameter named arrayToSort of the function selectionSort is actually of type char (*)[9999] and when calling this function you're passing dnaArray which is of type char*. That is, there is a mismatch in the type of the argument(dnaArray) and the type of the parameter(arrayToSort).


You should also refer to Why should I not #include <bits/stdc++.h>?.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • @AndreasWenzel Here is the [demo](https://onlinegdb.com/9aTY0zfZf) which shows that a `char` is passed to `strcpy` where a `const char*` is expected. – Jason May 17 '22 at 04:23
  • @AndreasWenzel Ok, let me recheck and i will remove the additional problems part from my answer. – Jason May 17 '22 at 04:45
  • @AndreasWenzel I have removed that part saying `strcpy` was called with invliad arguments in the original code. – Jason May 17 '22 at 04:49
  • I don't think that your proposed solution actually solves the problem. OP appears to have a working sorting function to sort an array of strings, but OP is incorrectly attempting to use that function on a single string. I believe the problem is that OP is only passing the last line of the file to the sorting function, instead of all lines of the file as an array of strings. – Andreas Wenzel May 17 '22 at 05:36
  • @AndreasWenzel I agree. I posted the answer just so that OP can understand what is the actual problem that is currently reported by the compiler. I may very soon delete this answer. – Jason May 17 '22 at 05:38
  • If you only delete the middle of your answer, but leave the start and the end intact, then I will upvote it. The first part of the answer does answer OP's immediate question. I am currently writing my own answer to explain the actual problem to OP. – Andreas Wenzel May 17 '22 at 05:41
  • @AndreasWenzel Updated. Thanks for the suggestion that the `strcpy` error that i originally mentioned was due to my proposed solution and hence i removed it. – Jason May 17 '22 at 05:43
1

You have declared selectionSort to take as a parameter a "pointer to an array of char of length MAX_LEN", but in the line selectionSort(dnaArray,line.length());, you are instead passing a "pointer to a char".

You appear to have a working sorting function for sorting an array of strings, but you are only passing a single string to that function. You must pass it an array of strings instead.

Your problem seems to be that you don't have an array of strings, because you are only remembering the first line of the input file. You must allocate memory for remembering all lines of the input file, and then pass all of these lines as an array of strings to the input file.

Your sorting function seems to expect an array of C-style null-terminated strings. However, your task would be easier to accomplish if you rewrote your sorting function to expect a std::vector of std::string instead.

Here is a solution which passes a array of C-style strings to your function selectionSort:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>

#define MAX_STRINGS 200
#define MAX_STRING_LEN 100

void selectionSort( char arrayToSort[][MAX_STRING_LEN], int n );

int main() 
{
    std::ifstream fin( "input.txt" );
    std::string line;

    //declare array of strings as static, so that there is
    //no risk of a stack overflow
    static char strings[MAX_STRINGS][MAX_STRING_LEN];
    size_t num_strings = 0;

    while( std::getline( fin, line ) )
    {
        if ( num_strings == MAX_STRINGS )
        {
            std::cerr << "Too many strings found in input file!\n";
            std::exit( EXIT_FAILURE );
        }

        //attempt to copy string
        if ( std::snprintf( strings[num_strings], sizeof *strings, "%s", line.c_str() ) >= (int)sizeof *strings )
        {
            std::cerr << "String too long!\n";
            std::exit( EXIT_FAILURE );
        }

        //update number of strings in array
        num_strings++;
    }

    //call sorting function
    selectionSort( strings, num_strings );

    //print the sorted array
    for ( size_t i = 0; i < num_strings; i++ )
    {
        std::cout << strings[i] << '\n';
    }
}

//This function was copied from OP's code, with minor
//modifications, such as renaming macro constants,
//adding "std::" and removing an unused variable.
void selectionSort( char arrayToSort[][MAX_STRING_LEN], int n )
{
    int i,j;
    char minStr[MAX_STRING_LEN];
    for (i=0;i<n-1;i++)
    {
        int min_idx=i;
        std::strcpy(minStr,arrayToSort[i]);
        for(j=i+1;j<n;j++)
        {
            if (std::strcmp(minStr, arrayToSort[j])>0)
            {
                std::strcpy(minStr,arrayToSort[j]);
                min_idx=j;
            }
        }   
        if (min_idx !=i)
        {
            char temp[MAX_STRING_LEN];
            std::strcpy (temp, arrayToSort[i]);
            std::strcpy(arrayToSort[i],arrayToSort[min_idx]);
            std::strcpy(arrayToSort[min_idx],temp);
        }
    }
}

For the input

cake
tomato
horse
cheese
apple
fork
carrot
dog
orange
cat

this program has the following output:

apple
cake
carrot
cat
cheese
dog
fork
horse
orange
tomato

As you can see, your sorting function works.

Here is a solution which uses std::vector<std::string> instead:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstdlib>

void selectionSort( std::vector<std::string> &strings );

int main() 
{
    std::ifstream fin( "input.txt" );
    std::string line;

    std::vector<std::string> strings;

    while( std::getline( fin, line ) )
    {
        //move string to array
        strings.emplace_back( std::move( line ) );
    }

    //call sorting function
    selectionSort( strings );

    //print the sorted array
    for ( auto str : strings )
    {
        std::cout << str << '\n';
    }
}

//this function has been modified to use the type
//std::vector<std::string>
void selectionSort( std::vector<std::string> &strings )
{
    int i,j;
    std::string minStr;
    for ( i=0; i < (int)strings.size()-1; i++ )
    {
        int min_idx=i;
        minStr = strings[i];
        for( j=i+1; j < (int)strings.size(); j++ )
        {
            if ( minStr > strings[j] )
            {
                minStr = strings[j];
                min_idx = j;
            }
        }
        if ( min_idx != i )
        {
            std::swap( strings[min_idx], strings[i] );
        }
    }
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39