0

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 :(

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
Kevdor
  • 31
  • 7
  • Possible duplicate of [What is a segmentation fault?](https://stackoverflow.com/questions/2346806/what-is-a-segmentation-fault) – JGroven Nov 07 '17 at 22:27
  • You have at least one memory leak, when you overwrite `input[0]`. – Some programmer dude Nov 07 '17 at 22:29
  • As for your problem, I recommend you take some time to read [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) by Eric Lippert, and learn how to use a debugger to catch crashes like this. – Some programmer dude Nov 07 '17 at 22:31
  • A couple of hints though, your code doesn't really do what you think it does, and you pass a null pointer as destination for `strcat`. – Some programmer dude Nov 07 '17 at 22:31
  • And you don't need `strcat` here at all. – Eugene Sh. Nov 07 '17 at 22:32
  • Would not ask here if my code did what I thought it should...As I said..my main confusion is how/what I have to pass to the function for it to actually do what I want it to do – Kevdor Nov 07 '17 at 22:56
  • Lots can be done. You didn't really ask a question. You don't show the output you get. What have you done to fix whatever the problem is? – LawfulEvil Nov 07 '17 at 23:01
  • Simple question: in `main()`, `dest[0]` (whom you call `*dest`) is a pointer to one or more characters. *Where is the memory for `dest[0]` allocated?* – AlexP Nov 07 '17 at 23:31

1 Answers1

2

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!

txtechhelp
  • 6,625
  • 1
  • 30
  • 39