2
    pf = fopen(leggere_filename(partita), "r");
    if (pf != NULL)
    {
        char line[256];
        count = 0;
        while (fgets(line, sizeof line, pf) != NULL) //read a line
        {   
            if (count == 8) {
                bool turno;
                char *end_string;
                char *string = strtok_s(line, "", &end_string);
                while (string != NULL) {
                    if (atoi(string) == 1)
                        turno = true;
                    else
                        turno = false;
                    string = strtok_s(NULL, "", &end_string);
                }
                partita = scrivereturno(partita, turno);
            }

hi, I need to take a string from the file and separate the numbers through the strtok_s function. The program works but brings me warnings with this message:

char * string: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int',

and:

int strtok_s (): implicit declaration of function 'strtok_s' is invalid in C99.

How come? I will appreciate your help.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Universe
  • 23
  • 2

1 Answers1

3

strtok_s is defined in the Annex K of the C Standard. These so called secure functions are optional and available mostly on Microsoft systems but with semantics different from the standard ones.

These functions are thus non portable and should not be used.

Another possible explanation is you did not include <string.h>. You should post a full program so every possible explanation can be found.

You can either use strtok(), which has several shortcomings but not a problem in your code, or the POSIX alternative strtok_r if available on your system.

Note however that passing an empty string as the delimiter string is meaningless. The second argument should be a string with possible delimiters, such as ' ', '\t', '\n' for whitespace or explicit delimiters such as ','.


The Microsoft documentation specifies this prototype:

char* strtok_s(
   char* str,
   const char* delimiters,
   char** context
);

Whereas the C Standard has this one:

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
char *strtok_s(char * restrict s1,
               rsize_t * restrict s1max,
               const char * restrict s2,
               char ** restrict ptr);

Even the prototypes are different and incompatible. Don't use this function.

The POSIX function strtok_r, a reentrant version of strtok has this prototype:

char *strtok_r(char *restrict str, const char *restrict delim,
               char **restrict saveptr);

which is compatible with Microsoft's version of strtok_s'. A more portable approach would be to use strtok_r and add these lines for compatibility on Windows:

#ifdef _MSC_VER
#define strtok_r(s,d,c)  strtok_s(s,d,c)
#endif

For a more complete discussion on Annex K functions, see this question:

Do you use the TR 24731 'safe' functions?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    Helpful links [Annex K](http://port70.net/~nsz/c/c11/n1570.html#K) and [K.3.7.3.1 The strtok_s function](http://port70.net/~nsz/c/c11/n1570.html#K.3.7.3.1) – David C. Rankin Jun 02 '22 at 20:28
  • 1
    Note that the Microsoft `strtok_s()` function is compatible with POSIX `strtok_r()` but not compatible with Annex K `strtok_s()`. See also [Do you use the TR-24731 'safe' functions?](https://stackoverflow.com/q/372980/15168) – Jonathan Leffler Jun 02 '22 at 22:55