简体   繁体   中英

strlen inconsistent with zero length string

I'm creating a DataStage parallel routine, which is a C or C++ function that is called from within IBM (formerly Ascential) DataStage. It is failing if one of the strings passed in is zero length. If I put this at the very first line of the function:

return strlen(str);

then it returns 0 for the calls that pass in empty values into str. If I put this at the first line, however...

if (strlen(str)==0) {return 0;}

then it does not return and goes into an infinite loop

I'm baffled - it works fine in a test harness, but not in DataStage.

Maybe there is something odd about the way DataStage passes empty strings to C routines?

int pxStrFirstCharList(char *str, char *chars )
{
  if (strlen(str)==0) {return 0;}
  if (strlen(chars)==0) {return 0;}
  int i = 0;
  //Start search
  while (str[i]) //for the complete input string
  {
    if (strchr(chars, str[i]))
    {
      return i+1;
    }
    ++i;
  }
  return 0;
}

There is a builtin function for what you are doing, it's called strcspn . This function takes two strings, and searches the first one for the first occurance of any of the characters of the second string.

I suggest using that than RYO...

http://www.cplusplus.com/reference/clibrary/cstring/strcspn/

I guess it is the strlen's issue when the length of the string is 0. For example,

char s1[0]; char *s2="a";

printf("%d %s\\n", sizeof(s1), s1);//0 @

printf("%d %s\\n", strlen(s1), s1);//3 @

printf("%d %s\\n", sizeof(s2), s2);//8 a

printf("%d %s\\n", strlen(s2), s2);// 1 a

You will get a weird answer for using strlen and you can check its source code in detail( https://code.woboq.org/userspace/glibc/string/strlen.c.html ). In nutshell, you can use sizeof instead of strlen for char string or avoid 0 length case by using strlen.

How about this?

int pxStrFirstCharList(char *str, char *chars )
{
  if (str && chars && (0 != strlen(str)) && (0 != strlen(chars)))
  {
    int i = 0;
    //Start search
    while (str[i]) //for the complete input string
    {
      if (strchr(chars, str[i]))
      {
        return i+1;
      }
      ++i;
    }
  }
  return 0;
}

Also, I don't quite get the point of the while loop ... (and no, I don't mean that this could be written as for ). What I mean is that on one hand you are doing a search ( strstr ) that itself will be implemented as a loop and still you have some outer loop. Could it be that you actually wanted to have chars in its place, ie:

int pxStrFirstCharList(char *str, char *chars )
{
  if (str && chars && (0 != strlen(str)) && (0 != strlen(chars)))
  {
    int i = 0;
    //Start search
    while (chars[i]) //for the complete input string
    {
      if (strchr(str, chars[i]))
      {
        return i+1;
      }
      ++i;
    }
  }
  return 0;
}

...? That is, look for each of the characters within chars inside the string denoted by str ...

If NULL is not explicitly part of the game, at least during development phase, it's always a good idea to add a precondition check on pointers received by a function:

int pxStrFirstCharList(char *str, char *chars )
{
  if (!str)
    return -1;

  if (!chars)
    return -2;
....

(The negative values -1 and -2 than tell the caller that something went wrong)

Or doing it in a more relaxed way, silently accepting NULL pointer strings as ""-string:

int pxStrFirstCharList(char *str, char *chars )
{
  if (!str)
    return 0;

  if (!chars)
    return 0;
...

If you are the only one using this API you could #ifndef BUILD_RELEASE these checks away for a release build if anything is tested stable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM