-1

One of the many forms I have tried is

    char *text, ebuf[32];
    int *num;     
    strncpy (ebuf,tfp->d_name,strlen(tfp->d_name));
    sscanf (ebuf, "%s_%i.txt", text, num);

I started originally with tfp->d_name in place of the ebuf hack, with the same results: segment faults. I understood from the man page that perhaps the %s should be %4c (text string has 4 characters - but not always). Anyway %4c or 4%c didn't make any difference.

Thanks to all who responded. Your clarifications - especially WhozCraig's "better man page" - put me on the right track.

The initialization issue was not my major problem, it was the syntax of the sscanf. For my program, once initialization was out of the way, the single line I really needed was:

      sscanf (tfp->d_name, "%[^_]_%i", &text[0], &num);
inbits
  • 1
  • 1
  • Fyi, likely [a much better man page](http://en.cppreference.com/w/c/io/fscanf) – WhozCraig Sep 28 '16 at 06:07
  • 1
    `text` is a pointer to......nothing. You must create something to point to: using [malloc](http://man7.org/linux/man-pages/man3/free.3.html) or a static array. The same for `num`. – LPs Sep 28 '16 at 06:07
  • `text` points to a random block of memory, which scanf will attempt to overwrite – Paul Stelian Sep 28 '16 at 06:08
  • 1
    `char text[sizeof ebuf]; int num;` ... `sscanf(ebuf, "%[^_]_%i.", text, &num);` – BLUEPIXY Sep 28 '16 at 06:10
  • There are many issues: one of them : `strncpy (ebuf,tfp->d_name,strlen(tfp->d_name));` -> `strncpy (ebuf,tfp->d_name,strlen(tfp->d_name) + 1);`, otherwise you won't copy the terminating NUL character. But BTW you don't need to copy the `tfp->d_name` string to `ebuf`, you can directly scan from `tfp->d_name`. – Jabberwocky Sep 28 '16 at 06:16

1 Answers1

1

Your pointer are not inizialize, so are pointing to nothing consistent.

You can allocate space for them using malloc, like:

char *text = malloc(max_len);
int *num = malloc(sizeof(int));
// ....
free(text);
free(num);

As you can see mallocated memory must be freed to release the allocated memory.

Otherwise you can use a simple variable and an array to store your

char text[max_len];
int num;
// ...
sscanf (ebuf, "%s_%i.txt", text, &num);

Take a look at this SO question to understand how you can manage to trigger a '_' as string delimiter. So, as BLUEPIXY commented you:

sscanf(ebuf, "%[^_]_%i.", text, &num);

Last thing, you can avoid the strncpy, and sscanf directly to tfp->d_name

sscanf(tfp->d_name, "%[^_]_%i.", text, &num);

This also avoid the "explosion" of sscanf due to the no null terminated ebuf string: You should use strlen(tfp->d_name)+1 as third parameter of your strncpy to copy to ebuf the null terminator too.

As strlen Man says:

DESCRIPTION

The strlen() function calculates the length of the string pointed to by s, excluding the terminating null byte ('\0').

emphasis mine

Community
  • 1
  • 1
LPs
  • 16,045
  • 8
  • 30
  • 61