I have to write a program that finds a pattern in a text using Brute-force method.
I have made functions to read the text file, pattern file and to execute the brute force algorithm(called match). These are called in main(). i need to store the index (at which the pattern is found in the text file)in an array and then print out that array in main.
How do I pass the array by reference??? Please help!!
the program gives an error that you cannot pass an array by reference.
Also, whenever I declare an array (in the function, match()) like this:
int arr[text_file_size]; (text_file_size is the size of the text file obtained by fseek() and ftell())
the program gives an error that you cannot initialize a constant array of size 0.
I printed out the text_file_size,it was not zero.
Please help.

Recommended Answers

All 15 Replies

declare the array as int *arr
i think it ll work

As firdousahmad said, you have to declare it in your calling function as void function(int *a). Let's see an example:

#include <iostream>
using namespace std;

void ssum(int* ar){
    for (int i=0;i<5;i++){
        ar[i]=ar[i]+100;
    }
}

int main(){
    int array[5]={2,5,6,7,8};
    ssum(array);
    for (int i=0;i<5;i++){
        cout<<array[i]<<" ";
    }
    return (0);
}

Another way to do it, if you have it in a struct, you can pass it by the reference using the reference operator &.
Here's another example:

#include <iostream>
using namespace std;
#define max 5

struct array{
    int ar[max];
};

void ssum(array &arra){
    for (int i=0;i<max;i++)
        arra.ar[i]=arra.ar[i]+100;
}

int main(){
    array arra;
    for (int i=0;i<max;i++)
        arra.ar[i]=i;
    ssum(arra);
    for (int i=0;i<max;i++)
        cout<<arra.ar[i]<<" ";
    return (0);
}

Here you are passing the whole struct by refference.
But mainly, you can pass it by defining it as int *.
As an aside note: post the code which chrashes the program, and the error corresponding to it.

In C++ you can certainly pass an array directly by reference:

#include <iostream>

using namespace std;

void foo(int (&a)[10])
{
    for (int i = 0; i < sizeof a / sizeof *a; ++i)
    {
        cout << a[i] << '\n';
    }
}

int main()
{
    int x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    foo(x);
}

However, that's not suitable as a solution because this is clearly not a real array we're talking about (unless you depend on a compiler extension) since its size depends on runtime information. Arrays in C++ must have a compile time constant size. Also, when passing an array by reference, the argument size must match the parameter size. An array of size 11 is incompatible with an array of size 10, for example.

Remi, post your code so that we can see what you're talking about. It's possible you're using C instead of C++, or relying on a compiler extension, both of which change the best solution for your problem.

Another thing, arrays are by default passed by reference in C++.

Another thing, arrays are by default passed by reference in C++.

Nope, they're passed as a pointer to the first element. This is a subtle but significant difference.

Well yes, they are pass as pointers, and thus, by pointer arithmetic, you can move around the memory.
As a concept, arrays are blocks of sequential memory, and when passing an array, you pass the pointer to its first position, the position 0 for that part of memory. And, when, for example, you want to access the element 5 from an array, by array[5] you will tell the compiler to go to the memory pointed by that pointer plus another 5 positions.
Perhaps that's why many books consider passing an array as always being passed by reference.

the pointer points to base address of array and rest it increments the pointer as the type of array

Perhaps that's why many books consider passing an array as always being passed by reference.

Certainly not any good books. Like I said, there's a subtle but significant difference between a pointer and a true reference.

#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

int match(char *pattern,char *text,int text_file_size,int pattern_file_size);
char* textread();
char* patternread();

int main( )
{   
    char *pattern;
    char *text;
    int text_file_size;
    int pattern_file_size;
    text=textread();

    pattern=patternread();

    int count=0;

    count = match(pattern, text,strlen(text),strlen(pattern));
    delete text;
    delete pattern;
    printf("the number of times the pattern occurs in text is %d", count);
    getch();
    return -1;


}

char* textread()
{   FILE *f_text;
    f_text = fopen( "C:\\data\\file1.txt" , "r");
    fseek(f_text, 0, SEEK_END);
   int text_file_size = ftell(f_text);

    fclose(f_text);
    f_text = fopen( "C:\\data\\file1.txt" , "r");
    char *text;
    text = new char[text_file_size+1];
    text[text_file_size]='\0';
                if(f_text != NULL)
                {
                    fread( text, sizeof(char), text_file_size,f_text);
                }

     fclose(f_text);
     return text;

}
char* patternread()
{
     FILE *f_pattern;
    f_pattern = fopen ( "C:\\data\\file2.txt" , "r");
    fseek (f_pattern,0, SEEK_END);
    int pattern_file_size = ftell (f_pattern);

    fclose(f_pattern);
    f_pattern = fopen ( "C:\\data\\file2.txt" , "r");
    char *pattern;
    pattern = new char[pattern_file_size+1];
    pattern[pattern_file_size]='\0';


            if(f_pattern!= NULL)
                {
                    fread(pattern, sizeof(char),pattern_file_size ,f_pattern);
                }
    fclose(f_pattern);
    return pattern;

}

int match(char *pattern, char *text, int text_file_size, int pattern_file_size)
{
int i, j,k;
int index=-1;
int count=0;
int arr[text_file_size]; //whenever i do this, it gives an error saying that you cannot pass an arry of constant size 0
for( i=0; i<=text_file_size-pattern_file_size; i++)
{
    index=k=i;
    for(j=0;j<pattern_file_size;j++)
    {       if(pattern[j]==text[k])
            {k++;}
            else break;
    }


    if(j==pattern_file_size)
    { 
        count=count+1;
        //printf ("the string is found at index %d \n" ,i );

    }

}
return count;               
}

I am reading two files (pattern and text and finding the pattern in the text. Instead of printing out the index in match(), i want to put them in an array and then print that array out in main.
I was told to read the file by using SEEK_SET in fseek to avoid opening the file again.But I don't know how to implement it.
I am new at C++ and i am compiling it in visual studio.So, it doesn't give errors when i use C..

I was told to read the file by using SEEK_SET in fseek to avoid opening the file again.But I don't know how to implement it.

Just read the file again. It's not gonna kill you, and it'll certainly keep your code simpler and less buggy. ;)

int arr[text_file_size];

This is your problem. As I explained, arrays in C++ must have a compile time constant size. If you want to have a "dynamic" array then you must either simulate it through pointers and dynamic memory (not recommended), or use one of the many standard library options such as std::vector (highly recommended).

By the look of things, you've so far chosen the former, and you clearly already know how to simulate an array because it's being done in both textread() and patternread(). Just duplicate that logic and you'll be sorted.

Note to nitpickers: I didn't mention pairing new with delete because I didn't want to avoid overwhelming the OP. It's not a long running program, and we all know that Windows reclaims dynamic memory when the process terminates.

But the arrays that I creatd in textread() and patternread() are being returned.
Since the match function is already returning the count, how do I return the array of indexes??

But the arrays that I creatd in textread() and patternread() are being returned.

Sorry, I missed that you're deleting them in main(). However, there's still a bug there, and those two lines should be:

delete[] text;
delete[] pattern;

You pair new with delete and new[] with delete[].

Since the match function is already returning the count, how do I return the array of indexes??

This is different. Dynamic memory and pointers are used for more than just extending the lifetime of the memory. In this case you simply cannot generate a real array with a runtime size because its size depends on a compile time constant. Even if you free the memory before returning, it's still necessary to allocate some dynamically.

int match(char *pattern, char *text, int text_file_size, int pattern_file_size)
{
    int i, j, k;
    int index = -1;
    int count = 0;
    int* arr = new int[text_file_size];

    ...

    delete[] arr;

    return count;               
}

It's just that simple.

Thank you deceptikon...thanks a lot!!!
You've helped me so much and I am really thankful. :)
Thank you firdousahmad and Lucaci Andrew...thank you for the time and help..I really appreciate that..:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.