Need instruction on string initialization

I have an assignment in which I need to write a program that will take letters in the first line of parameters and find them in the second line of parameters, for example:

./a.out "lolabab" "ablcocllcab"

the program needs to print "loab"

as each letter only needs to be printed once. here is the main part of my program

char    *do_stuff(char *s1, char *s2)
{
    int     i, j, k;
    char    *out;

    out = malloc(sizeof(char) * str_len(s1));
    i = 0;
    j = 0;
    k = 0;
    while (s2[j] != '\0' && s1[i] != '\0')
    {
        if (s2[j] == s1[i])
        {
            if (check_char(out, s1[i]) == 0)
            {
                out[k] = s1[i];
                k++;
            }
            i++;
            j = -1;
        }
        j++;
    }
    return (out);
}

      

my question is, if i don't initialize "out"

i have a problem. i initialize it with malloc

for now, but I'm not allowed to use malloc

:). any other way i tried doesn't seem to work for me (segmentation fault). So how do I initialize a string without using malloc? This is probably obvious, but I am new to this, so pls help. Thank!

+3


source to share


3 answers


If I understand correctly what you want, you shouldn't create a new line, but use the command line options available in the arguments main()

.

When you write

int main(int argc, char** argv) {

      

The compiler will arrange so that argc

is the number of command line arguments, and argv

is an array of strings with arguments. The first argv[0]

is the name of the program, and the rest are the arguments passed to the program.

So this is one way to get your assignment done (for high-level description only - the rest is yours!)

Take the first argument argv[1]

and move on to it, character by character. For each character, try to find it in a different argument argv[2]

. If you find it, type a single character.



No need to allocate memory at all!

edit: if you don't want to print duplicates, then one way is to keep a static array that you could use as an index of the characters already printed:

static int printed[26] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

      

When you type c

, set its position to 1. And only print if the character position is zero.

It's up to you how to find the index of an arbitrary character (and decide if you want to distinguish between upper and lower case).

+1


source


You can always pass the output buffer as a parameter

void do_stuff(char *s1, char *s2, char *out /* some large enough char [] */)
{
    int     i, j, k;

    i = 0;
    j = 0;
    k = 0;
    while (s2[j] != '\0' && s1[i] != '\0')
    {
        if (s2[j] == s1[i])
        {
            if (check_char(out, s1[i]) == 0)
            {
                out[k] = s1[i];
                k++;
            }
            i++;
            j = -1;
        }
        j++;

    }
}

      

and in the calling function



char result[SOME_REASONABLE_SIZE] = {0} /* initialize it for the check_char function */;
do_stuff(argv[1], argv[2], result);

      

you have to check that the function received 2 arguments, of course.

One more thing, try not to use strlen

char in the test function, pass it the length of the string k

, so your program will be more efficient.

+1


source


Use the fact that the character count is constant (and relatively small):

#include <limits.h>

#define CHAR_NUM (1<<CHAR_BIT)
#define FLAG(x)  (1<<(x))

void get_common_chars(char* s1,char* s2,char out[CHAR_NUM])
{
    int i,n;
    int flags[CHAR_NUM] = {0};

    for (i=0; s1[i]!=0; i++)
        flags[(unsigned char)s1[i]] |= FLAG(1);

    for (i=0; s2[i]!=0; i++)
        flags[(unsigned char)s2[i]] |= FLAG(2);

    n = 0;
    for (i=0; i<CHAR_NUM; i++)
        if (flags[i] == FLAG(1)|FLAG(2))
            out[n++] = (char)i;
    out[n] = 0;
}

      

If you are interested in narrow letters, you can improve it:

#define MIN_CHAR 'a'
#define MAX_CHAR 'z'
#define CHAR_NUM (MAX_CHAR-MIN_CHAR+1)
#define FLAG(x)  (1<<(x))

void get_common_chars(char* s1,char* s2,char out[CHAR_NUM])
{
    int i,n;
    int flags[CHAR_NUM] = {0};

    for (i=0; s1[i]!=0; i++)
        if (MIN_CHAR <= s1[i] && s1[i] <= MAX_CHAR)
            flags[s1[i]-MIN_CHAR] |= FLAG(1);

    for (i=0; s2[i]!=0; i++)
        if (MIN_CHAR <= s2[i] && s2[i] <= MAX_CHAR)
            flags[s2[i]-MIN_CHAR] |= FLAG(1);

    n = 0;
    for (i=0; i<CHAR_NUM; i++)
        if (flags[i] == FLAG(1)|FLAG(2))
            out[n++] = (char)(MIN_CHAR+i);
    out[n] = 0;
}

      

Here's a usage example:

#include <stdio.h>

int main(int argc,char* argv[])
{
    char common_chars[CHAR_NUM];
    if (argc >= 3)
    {
        get_common_chars(argv[1],argv[2],common_chars);
        printf("%s\n",common_chars);
    }
    return 0;
}

      

+1


source







All Articles