0

So I have a char array formed by words separated by spaces. The array is read from the input. I would like to print the words that start with a vowel.

My code:

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

char *insertt (char dest[100], const char sou[10], int poz) {

    int cnt=0;

    char *fine = (char *) malloc(sizeof(char) * 3);
    char *aux = (char *) malloc(sizeof(char) * 3);

    strncpy(fine,dest,poz);

    strcat(fine,sou);

    do {
        aux[cnt]=dest[poz];
        poz++;
        cnt++;
    }
    while (poz<=strlen(dest));

    strcat(fine,aux);
    free(aux);

    return fine;
    } 


int check_vowel(char s) {
    switch (s) {
        case 'a':
        case 'e':
        case 'i':
        case 'o':
        case 'u':
        case 'A':
        case 'E':
        case 'I':
        case 'O':
        case 'U':
            return 1;
        default: return 0;

    }
}

    int main (void) {

        const char spc[]=" ";
        char s[100];
        char *finale = (char *) malloc(sizeof(char) * 3);
        int beg,len,aux; //beg - beginning; len - length;
        int i = 0;


        printf("s=");
        gets(s);


        finale = insertt(s,spc,0); //the array will start with a space

        do {
           if (finale[i]==' ' && check_vowel(finale[i+1])==1) {
               beg=i+1; //set start point
               do { //calculate length of the word that starts with a vowel
                    len++;
               }        
               while(finale[len]!=' '); //stop if a space is found
                   printf("%.*s\n", len, finale + beg); //print the word
           }

        i++;
        }
        while (i<=strlen(finale)); //stop if we reached the end of the string

        free(finale);
        return 0;


    }

The check_vowel function will return 1 if the character is a vowel, otherwise, it returns 0. The insertt function will insert a const char into a char from a specified position, I used it to insert a space at the beginning of the array.

The input: today Ollie was ill
The output: Segmentation fault (core dumped)
Preferred output: 
Ollie
ill

I'm sure the problem is somewhere in the main do-while loop, but I just can't figure out what might be it... The 2 functions work correctly. Thanks!

Feri Csokatu
  • 17
  • 1
  • 5

2 Answers2

1

Well there are lot many errors in your program that may cause a SIGSEGV.

1) The fine & aux pointers in the function insertt haven't been allocated with sufficient amount of memory. Change it to say:

char *fine = malloc(sizeof(char) * 300);

2) In the outer do while{} loop, the condition must be:

i<strlen(finale)

3) In the inner do while{}, the condition must be:

while(len<strlen(finale) && finale[len]!=' ');

EDIT:

There is still a logical error in your code, which I leave it to you to figure it out:

For string:

adfajf isafdadsf ifsfd

Your output was:

adfajf 
isafdadsf ifsfd
ifsfd

which is incorrect!!

nitish712
  • 19,504
  • 5
  • 26
  • 34
  • Please don't suggest casting the return value of `malloc()`, even if OP's code includes that mistake. –  Oct 06 '13 at 11:16
  • Hey! Thank you! After applying your suggestions, it doesn't core dump anymore. I also noticed that there might be a logical error but I couldn't figure out where... Anyways, for "adfajf isafdadsf ifsfd" my output is: `adfajf isafdadsf ifsfd\n isafdadsf ifsfd\n ifsfd\n` It's weird but I'll search around the code for that logical mistake :) – Feri Csokatu Oct 06 '13 at 11:39
0

Alternative approach, using a small finite state machine. The string is modified in place. The strategic use of break and continue avoids a lot of conditionals. (the only remaining condition it the for the addition of a space before the second and next selected words)

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

int classify(int ch)
{
switch(ch) {
case 'a': case 'A':
case 'e': case 'E':
case 'i': case 'I':
case 'o': case 'O':
case 'u': case 'U':
case 'y':case 'Y':
        return 1;
case ' ': case '\t': case '\n':
        return 0;
default:
        return 2;
        }
}

size_t klinkers_only(char *str)
{
size_t src,dst;
int type,state;

for (state=0, src=dst=0; str[src] ; src++) {
        type = classify( str[src] );
        switch(state) {
        case 0: /* initial */
                if (type == 1) { state =1; if (dst>0) str[dst++] = ' '; break; }
                if (type == 2) { state =2; }
                continue;
        case 1: /* in vowel word */
                if (type == 0) { state=0; continue; }
                break;
        case 2: /* in suppressed word */
                if (type == 0) { state=0; }
                continue;
                }
        str[dst++] = str[src];
        }

str[dst] = 0;
return dst;
}
int main(void)
{
size_t len;
char string[] = "abc def gh ijk lmn opq rst uvw xyz";

printf("String:='%s'\n", string );

len = klinkers_only(string);
printf("Return= %zu, String:='%s'\n", len, string );

return 0;
}
wildplasser
  • 43,142
  • 8
  • 66
  • 109