Kevdor
Kevdor

Reputation: 41

Manipulation array in function - c - Segmentation fault

So I started to learn how to code a few weeks ago, and this site helped me so much, thank you for that. But this time I got stuck and can´t really figure out why...Hope you can help me. Basically I have a function prototype I have to use in my program and I have my troubles with it. The function should receive a string and then only copy every second char of that string and return the result...

This is what I've got so far:

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

#define max_size 1000

char * everySecondChar(char * dest, char * input);

int main() {

    char inputstr[max_size] = {0}; 
    char *input[max_size] = {0};
    char *dest[max_size] = {0};
    char temp[max_size] = {0}; 
    int i = 0;

    while (fgets(inputstr, max_size, stdin) != NULL)
    {
        input[i] = strndup(inputstr, max_size);
        strcat(temp,inputstr);
        i++;

    }   
    input[0] = strndup(temp, max_size);

    printf("Inputted text:\n%s", *input);
    printf("\n");
    printf("\n");
    printf("Resulting string:\n");

    everySecondChar(*dest, *input);

    printf("%s", *dest);

    return 0;   
}

char * everySecondChar(char * dest, char * input)
{
    int i = 0;

    for(i = 0; i < max_size; i+=2) {
        strcat(dest,input);
    }

    return dest;
}

I know this is probably a 1-min challenge for the most of you, but I am having my troubles whenever I see those nasty * in a function prototype :(

Upvotes: 0

Views: 83

Answers (1)

txtechhelp
txtechhelp

Reputation: 6777

Congrats on getting started with programming!

To your question: there's quite a few things that could be addressed, but since there seems to be some more basic confusion and misunderstanding, I'll address what makes sense given the context of your issue.

First, you're using strcat which concatenates strings (e.g. adds to the string), when you just need simple character assignment.

Next, you have a lot of pointers to arrays and there seems to be some confusion regarding pointers; in your main function, you don't need all of the temporary variables to do what you're wanting.

You could have simply:

char inputstr[MAX_SIZE] = {0}; 
char dest[MAX_SIZE] = {0};

You could have less (realistically) but we'll stick with the basics for now.

Next, you're looping to get user input:

while (fgets(inputstr, max_size, stdin) != NULL)
{
    input[i] = strndup(inputstr, max_size);
    strcat(temp,inputstr);
    i++;
}

Here, you don't check if i exceeds max_size which your input variable has been allocated for; if i exceeds max_size when you go to assign input[i] to the memory location returned by strndup (which calls malloc), you are writing beyond your memory bounds, which is also known as a buffer overflow. This is potentially where your segmentation fault is happening. You could also have some issues when you do strcat(temp,inputstr); since strcat:

Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.

If you're simply just trying to get what the user entered, and print every 2nd character with your function, you don't need to loop:

if (fgets(inputstr, MAX_SIZE, stdin) != NULL) {
    everySecondChar(dest, inputstr);
    printf("Inputted text:\n%s\n\nResulting string:\n%s\n", inputstr, dest);
}

Lastly, in your everySecondChar function, you're using strcat again when all you need to do is simple assignment (which does a 'copy'):

char * everySecondChar(char * dest, char * input)
{
    int i, j;
    for(i = 0, j = 0; i < MAX_SIZE; ++i, ++j) {
        if (input[i] == 0) break; // end if string?
        dest[j] = input[i++];
    }
    return dest;
}

Putting all of it together, you get:

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

#define MAX_SIZE 1000

char * everySecondChar(char * dest, char * input);

int main(void)
{
    char inputstr[MAX_SIZE] = {0}; 
    char dest[MAX_SIZE] = {0};
    printf("Enter some text: ");
    if (fgets(inputstr, MAX_SIZE, stdin) != NULL) {
        everySecondChar(dest, inputstr);
        printf("Inputted text:\n%s\n\nResulting string:\n%s\n", inputstr, dest);
    }
    return 0;   
}

char * everySecondChar(char * dest, char * input)
{
    int i, j;
    for(i = 0, j = 0; i < MAX_SIZE; ++i, ++j) {
        if (input[i] == 0) break; // end if string?
        dest[j] = input[i++];
    }
    return dest;
}

That aside, I'll address some other things; typically if you have a constant value, like your max_size variable, it's considered "best practice" to capitalize the entire thing:

`#define MAX_SIZE 1000`

I am having my troubles whenever I see those nasty * in a function prototype :(

Those nasty *'s in your function prototype (and variable declarations) are known as a pointer qualifier; it indicates that the type of the variable is a pointer to the type specified. A pointer isn't something to be scared of, you're learning C, it's highly important you understand what a pointer is and it's utility.

I won't dive into all of the specificities of pointers, aliases, etc. etc. since that is beyond the scope of this Q&A, but WikiBooks has a great intro and explanation covering a lot of those concepts.

Hope that can help!

Upvotes: 2

Related Questions