user784637
user784637

Reputation: 16092

How to correctly prototype C functions

I'm learning the concept of prototyping in C, however I'm struggling with the correct syntax. I'm writing a function to strip all non-alphbetic characters from a c-string

#include <stdio.h>
#include <string.h>

char[30] clean(char[30] );

int main()
{
    char word[30] = "hello";
    char cleanWord[30];
    cleanWord = clean(word);
    return 0;
}


char[30] clean(char word[30])
{
    char cleanWord[30];
    int i;

    for(i=0;i<strlen(word);i++)
        if ( isalpha(word[i]) )
            cleanWord[i]=word[i];

    cleanWord[i]='\0';

    return cleanWord;
}

How do I correctly prototype the function? What are the other syntax errors that are preventing my program from compiling?

Upvotes: 1

Views: 221

Answers (3)

Nobilis
Nobilis

Reputation: 7448

A couple of notes (was a bit late with writing up an answer, seems I've been beaten to them by the others )

  1. C cannot return local (stack) objects, if you want to return an array from a function you have to malloc it

  2. Even if you declare an array argument as (char arr[30]), (char* arr) is just as valid as arrays decay to pointers when passed as arguments to functions. Also, you won't be able to get the size correctly of such arrays by using sizeof. Even though it's 30, on my machine it returns 4 for word in clean, which is the size of the pointer for it.

  3. You are missing an include, isalpha is part of ctype.h

I've updated your code, hopefully I've guessed your intentions correctly:

#include <stdlib.h> /* for malloc and free */
#include <string.h> /* for strlen */
#include <ctype.h>  /* for isalpha */
#include <stdio.h>  /* for printf */

/* Function declaration */
char* clean(char word[30]);

/* your 'main()' would now look like this: */
int main()
{
    char word[30] = "hel1lo1";

    char* cleanWord;

    cleanWord = clean(word);

    printf("%s\n", cleanWord);

    free(cleanWord);

    return 0;
}

/* Function definition */
char* clean(char word[30])
{
    char* cleanWord = malloc(30);   /* allocating dynamically an array of 30 chars, 
                                     * no need to use sizeof here as char is 
                                     * guaranteed to be 1 by the standard 
                                     */

    unsigned int i, j = 0; /* let's fix the problem with non-alpha chars already pointed out */

    for (i = 0; i < (strlen(word)); i++)
        if (isalpha(word[i]))
            cleanWord[j++] = word[i]; 


    cleanWord[j] = '\0';

    return cleanWord; 
    /* return a pointer to the malloc`ed array, don't forget to free it after you're done with it */
}

Upvotes: 3

paddy
paddy

Reputation: 63451

As Carl Norum said, you can't return an array. Instead, what you tend to do is supply the output:

void clean( const char word[30], char cleanWord[30] )
{
}

And you should remove the locally-scoped array from that function.

You will find that the function does not work correctly, because you only have one iterator i. That means if a character is not an alpha, you will skip over a position in the output array. You will need a second iterator that is incremented only when you add a character to cleanWord.

Upvotes: 3

Carl Norum
Carl Norum

Reputation: 224844

Your problem is not with function prototyping (aka forward declaration). You just can't return an array from a function in C. Nor can you assign to an array variable. You need to make a couple of changes to get things working. One option:

  1. change char cleanWord[30] in main to be char * cleanWord.
  2. change the signature of clean to char *clean(char word[30])
  3. use malloc to allocate a destnation buffer inside clean
  4. return a pointer to that new buffer
  5. free the buffer in main

And another:

  1. change the signature of clean to void clean(char word[30], char cleanWord[30])
  2. operate on the passed-in pointer rather than a local array in clean
  3. change the call in main to be clean(word, cleanWord).

Upvotes: 7

Related Questions