why at line 12, the expression : (char)str+3 , adds the 2nd index to the string?
for example when str="123123" , (char
)str+3 is "3123" instead of "123" ?
input: 3 0 3 123123
output supposed to be: "Mybcmp result: 0" since the 3 indexes that's compared from b1="123123" and b2="123" are the same

    #include <stdio.h>
    #define LENGTH 128
    int my_bcmp (const void *b1, const void *b2, size_t len);
    int main()
    {
      int b1, b2, len;
      char str[LENGTH];
      printf("Enter length and two indexes followed by a string:\n");
      scanf("%d%d%d",&len,&b1,&b2);
      printf("Enter a string:\n");
      fgets (str, LENGTH, stdin);
      printf("len:%d strb1:%s  strb2:%s str:%s\n",len,(char*)str+b1,(char*)str+b2,str);
      printf("Mybcmp result: %d\n",my_bcmp((char*)str+b1,(char*)str+b2,len));
      return 0;
    }
    int my_bcmp (const void *b1, const void *b2, size_t len)
    {
      int i=len;
      const char* r1=(const char*)b1;
      const char* r2=(const char*)b2;
      while (i-- > 0)
        {
          if (*r1++ != *r2++)
          return -1;
        }
      return 0;
    }

Recommended Answers

All 10 Replies

That, sir, is a fantastic question.

My assumption is that the inline cast to a char * is somehow mangling the memory space on the stack, or the assumption of the pointer starts at a negative index to account for the pointer itself...

no idea :-/

That being said.. why not just make a pointer and use it?

commented: Good point. Never obfuscate your own code. +15

It looks to me that fgets is picking up whatever delimiter you're using after inputting b2 and adding it to the front of the input string. Thus, throwing off your offset.

One workaround for this is to get all your inputs at once:

int main()
{
    int b1, b2, len;
    char str[LENGTH];
    printf("Enter length and two indexes followed by a string:\n");
    scanf("%d%d%d%s", &len, &b1, &b2,str);
    printf("len:%d strb1:%s  strb2:%s str:%s\n", len, (char*)str + b1, (char*)str + b2, str);
    printf("Mybcmp result: %d\n", my_bcmp((char*)str + b1, (char*)str + b2, len));
    return 0;
}

@ryantroop im not quite sure how do i use one pointer for the whole string...(i forgot to mention that the string may contain spaces/tabs too and only ends with new line)
@tinstaafl samething here i forgot to mention that the input may include spaces/tabs(and should be able to press enter for each of the inputs, len, b1, b2 ) then lastly the string which ends with newline or EOF... im not sure how to do it
i tried %[^\n] in scanf but that ends it right after hitting Enter after b2 in the scanf:

scanf("%d%d%d%s", &len, &b1, &b2,str);

just wanted to avoid adding "+1" to the pointers in lines 12-13

so.. this worked for me using a pointer, but it still suffers from the offset. I believe that tinstaafl is correct in fgets including the last space/newline as a character in its read of the stdin pipe.

#include <stdio.h>
#define LENGTH 128
int my_bcmp (const void *b1, const void *b2, size_t len);
int main()
{
  int b1, b2, len;
  char str[LENGTH];
  char *pStr = str;
  printf("Enter length and two indexes followed by a string:\n");
  scanf("%d%d%d",&len,&b1,&b2);
  printf("Enter a string:\n");
  fgets (str, LENGTH, stdin);
  printf("len:%d strb1:%s  strb2:%s str:%s\n",len,pStr+b1,pStr+b2,str);
  printf("Mybcmp result: %d\n",my_bcmp(pStr+b1,pStr+b2,len));
  return 0;
}
int my_bcmp (const void *b1, const void *b2, size_t len)
{
  int i=len;
  const char* r1=(const char*)b1;
  const char* r2=(const char*)b2;
  while (i-- > 0)
    {
      if (*r1++ != *r2++)
      return -1;
    }
  return 0;
}

in an effort to prove that theory, we can simply convert the char at str[0] to a value and see what it has.

ex:

  printf("Value at str[0]: %d", *pStr); //get the numerical value of the char at this memory location.

when I added that line after fgets(...), I got a "32" which is the ascii value for a space.
http://www.theasciicode.com.ar/ascii-printable-characters/space-ascii-code-32.html

To continue answering your second question - a "string" in a buffer basically walks down contiguous memory until a null terminator is found. If you have a pointer to the beginning of the "string" you can keep going until you find a null (0). And if you want to break your code / the world, go ahead and move past the null terminator with the pointer because -- well, the language lets you so it's gotta have a reason, right? :-P In short.. don't go past the null.

One option to still use fgets is to capture the errant character(s) first before calling fgets:

int main()
{
  int b1, b2, len;
  char str[LENGTH];
  char* temp;
  printf("Enter length and two indexes followed by a string:\n");
  scanf("%d%d%d",&len,&b1,&b2);
  printf("Enter a string:\n");
  scanf("%s",temp);
  fgets (str, LENGTH, stdin);
  printf("len:%d strb1:%s  strb2:%s str:%s\n",len,(char*)str+b1,(char*)str+b2,str);
  printf("Mybcmp result: %d\n",my_bcmp((char*)str+b1,(char*)str+b2,len));
  return 0;
}

If I'm not mistaken the problem comes from C being developed for Unix-type systems which use a single linefeed(\n) character to terminate each line. Windows uses a carriage return character(\r) and a linefeed character(\n) to terminate each line, which complicates the streams operations.

On a side note, If you are developing on a windows machine the Visual Studios' debugger for C/C++ is one of the best.

It's not working because fgets get the entire string after the last digit picked up by scanf, incluse the space character between the digit and the string. So str is 'space','1','2',....
Just add a space after %d in scanf

If you're getting 2 separate inputs, why are you separating them by a space instead of pressing enter?

On a side note, If you are developing on a windows machine the Visual Studios' debugger for C/C++ is one of the best.

@tinstaafl: Indeed! But also for vb.NET, C# and F# windows developing I think it's hard to find any better.

The problem originates from the function "fgets"http://en.cppreference.com/w/c/io/fgets , when the input is: "3 0 3 123123", fgets will read the space in front of the "123123", so the variable str actually is
" 123123", which has strlen of 7!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.