0

Given program is working for string that is fixed in code for example

char str[100] = "With fixed string this code works"
// Output of the program is "fixed string this code works"

But as soon as I take the str input using

scanf("%s", &str);

it seems error is found with memory allocation because after input is given code returns error value.

The full code is as following

int main (void) {
    char str[100];
    char *p = (char *)malloc(sizeof(char) * str[100]);
    printf("Enter something: ");
    scanf("%s", &str);
    *p = str;
    p = strchr(str, ' ');
    puts(p + 1);

    // Check for the first space in given input string if found then 
    while (*p++)
        if (*p == ' ' && *++p)
            printf("%s", *p);

    printf ("\n\n");

    return 0;
}

Not sure if for dynamic memory allocation while using scanf function to input string any other allocation process is required

NAND
  • 663
  • 8
  • 22
  • Turn on all your compiler warnings and **read them**. You should be getting quite a few. – Andrew Henle May 24 '20 at 15:07
  • Just to check, are you trying to take a string from the user and then print out all characters after the first space? – CodeWash May 24 '20 at 15:27
  • @CodeWash yes, exactly that I am trying to do – user7254101 May 24 '20 at 15:28
  • @user7254101 After this assignment p = strchr(str, ' '); p is equal to NULL. – Vlad from Moscow May 24 '20 at 15:43
  • what *value* do you think you are passing to `malloc()`? take careful note of the answer from Craig Estey : you are passing in the *value found at* `str[100]`, which I'm guessing is not what you intend to be doing – landru27 May 24 '20 at 16:07
  • @user7254101 Forn starters explain what you are trying to achieve. – Vlad from Moscow May 24 '20 at 16:45
  • @VladfromMoscow Shouldn't `p` be equal to the address of first space? -http://www.cplusplus.com/reference/cstring/strchr/ – NAND May 24 '20 at 17:03
  • @NAND It is unclear whether fe wants to output each word or the whole string after a space. – Vlad from Moscow May 24 '20 at 17:05
  • Hey @user7254101 , Can you add more details on your post and sample input and output and consider give feedback on the answers, commenting to know specific detail, upvote or downvote ? – NAND May 24 '20 at 17:12
  • @NAND I want rest of the string after the first white space detected. And as of I could understand is that scanf is not the suitable function to take input with white spaces – user7254101 May 24 '20 at 23:00

3 Answers3

3

Your malloc has a bug:

char *p = (char *)malloc(sizeof(char)*str[100]);

Let's simplify a bit first.


Don't cast malloc (See: Do I cast the result of malloc?):

char *p = malloc(sizeof(char)*str[100]);

sizeof(char) is (by definition) always 1 on all architectures, regardless of how many bits it occupies, so we can eliminate it:

char *p = malloc(str[100]);

Now we have:

char str[100];
char *p = malloc(str[100]);

You have undefined behavior. str has no values (i.e. unitialized) and you are passing the element that is one past the end of the array, so you have undefined behavior.

So, the length parameter passed to malloc is, thus, random.

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
1

You have four problems:


First: with scanf, it should be like that:

scanf("%s",str);

because str is an address. Also make sure that scanf will scan for a string from stdin until it finds space or new line and that what you don't want. So you'd better use fgets(str, 100, stdin);.


Second: with malloc, it should be like that:

malloc(sizeof(char)*100)

because str[100] has not a specific value.


Third: You shouldn't change the address of memory allocated using malloc

malloc function allocates memory in heap and return the address of memory allocated, so you shouldn't do this p = strchr(str, ' '); since strchr will return the address of the first occurrence of the space (the address returned by malloc will be lost) .


Fourth: freeing the memory allocated using malloc

You should free the memory allocated using malloc using free function which take the address of the memory allocated.

Your code should be like that:

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


int main (void) {
    char str[100];
    char *p = malloc(sizeof(char)*100); //Do NOT cast the return of malloc
    printf("Enter something: ");
    fgets(str, 100, stdin); //Use fgets to include the spaces between words 
    strcpy(p, str);//use stcpy to Not change the address of memory allocated

    //p = strchr(str, ' '); -->This step will change the address
    //of memory allocated using malloc
    //puts (p + 1);
    /*Instead you can do this*/
    char *c = strchr(str, ' ');
    puts(c+1);

    // Check for the first space in given input string if found then 
    char *mem =p;
    while (*p++)
      if (*p == ' ' && *++p)
        printf ("%s", p);

    printf ("\n\n");
    free(mem);

    return 0;
}
NAND
  • 663
  • 8
  • 22
  • It is now printing several remainders for every detected white spaces. But my intention was to print just the remainder of the string only once after the first white space is found – user7254101 May 24 '20 at 23:04
  • 1
    I think what you want can be achieved after removing `while` loop , isn't it? :) – NAND May 24 '20 at 23:11
  • replacing `while (*p++)` with `if(*p++)` made it functioning what i was wanting it to. Thanks dude:) – user7254101 May 24 '20 at 23:34
  • 1
    @user7254101 Not at all ;). Also consider freeing memory allocated using `malloc` by using `free` function. I updated the answer :D. – NAND May 24 '20 at 23:36
0

Scanf %s only reads in a string up to the first whitespace and then stops, which is probably what is causing you problems. I would avoid scanf anyway, it's dangerous and can cause problems if you're not familiar with it. You could try fgets to read from stdin instead. See if this does what you want:

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

#define MAX_LENGTH 100

int main (void) 
{
    char *str = (char *) malloc (sizeof(char) * MAX_LENGTH + 1);
    bzero(str, MAX_LENGTH + 1);

    printf("Enter something: ");
    fgets(str, MAX_LENGTH, stdin);

    // Remove the newline
    if ((strlen(str) > 0) && (str[strlen (str) - 1] == '\n'))
    {
        str[strlen (str) - 1] = '\0';
    }

    char *p = strchr(str, ' ');

    if (p != NULL)
    {
        // Pointing to the space, which we will skip
        p++;
        printf ("%s\n\n", p);
    }
    return 0;
}
CodeWash
  • 155
  • 6
  • No need for memory allocation, no need to clear this memory, `bzero` is BSD specific and obsolete, test if `fgets()` returned `NULL`, use `str[strcspn(str, "\n")] = '\0';` to strip the newline if any. – chqrlie May 24 '20 at 20:18