0

This is a piece of my code down below, I have created a server and client which can communicate with each other. Everything works fine but when I add a space character to my message the program treats them as two different strings, meaning two different messages.

So when I type Hello I get back

Content-Length: 5;Hello

But When I type Hello dude I get back

Content-Length: 5;Hello
Content-Length: 4;dude

Here is the source code of the client who sends the message. To receive the messages I have created threads, but they all work fine. I assume this has to do with how send() function treats the space character . My question is, how do I get it to treat as if it was a real character?

  char msgtobesent[256];
  memset(msgtobesent, '\0', 256);
  while(TRUE){

    scanf("%s", msgtobesent);
    int ll = strlen(msgtobesent);
    char theTotalMessage[19];
  //  memset(theTotalMessage, '\0', sizeof(theTotalMessage));
    sprintf(theTotalMessage, "Content-Length: %d;", ll);
    strcat(theTotalMessage, msgtobesent);
    printf("theTotalMessage: %s\n", theTotalMessage);
    send(connection, theTotalMessage, strlen(theTotalMessage) + 1, 0);
  }
melpomene
  • 84,125
  • 8
  • 85
  • 148
Ahmed Can Unbay
  • 2,694
  • 2
  • 16
  • 33
  • This has nothing to do with `send` and everything with you using `scanf`. You could have figured this out yourself by preparing a [mcve]. – melpomene Oct 08 '17 at 12:58
  • I recommend never using `scanf` ever. – melpomene Oct 08 '17 at 13:01
  • 2
    @melpomene That seems a bit stubborn to me. What would you use in place of `scanf("%*[^\n]"); getchar();`, to read and discard a line of input (perhaps after `fgets` reads only a partial line)? – autistic Oct 08 '17 at 13:03
  • @Sebivor I don't think I've ever needed to discard a line of input, but I'd use `while ((c = getchar()) != EOF && c != '\n') ;`. – melpomene Oct 08 '17 at 13:06
  • `scanf("%[^\n]s",msgtobesent);` is my fav one from the answers. but what does `*` do as you have stated? do we even need to use it? @melpomene – Ahmed Can Unbay Oct 08 '17 at 13:17
  • 1
    `"%[^\n]s"` is wrong. That format string would scan for an `s` in the input. I said to never use `scanf`. – melpomene Oct 08 '17 at 13:19
  • @melpomene You forgot a declaration for `c`; since you want to mimic `scanf("%*[^\n]"); getchar();` you'll want to limit the scope for that declaration to the loop, so using a `for` loop might be more appropriate. You could use `fread` instead of `getchar`, to eliminate the nested brackets which are likely to take other people time to decipher, so your loop could (and should) look more like: `for (char c; fread(&c, 1, 1, stdin) && c != '\n'; );`. This is vastly superior to your loop from an educational point of view, as that declaration you've neglected is one of the major issues for `fgetc`, – autistic Oct 09 '17 at 09:20
  • ... and it's just easier to parse. Out of curiousity, how would you read a single `int` value, encoded as a sequence of decimal digits? Would you also need a temporary variable for *that*? How would you ensure you *only* read the `int` value (and not any more than that), if you're expected to do that. Otherwise, if you're required to read entire lines, how would you ensure *the entirety of the line* is read? `fgets` will *stop reading* when it reaches the size of the object, which would leave you with a very subtle bug to spend years debugging if you don't read manuals. – autistic Oct 09 '17 at 09:28
  • @melpomene If you dismiss `scanf` without so much as a second thought you're missing out on opportunities where it is the best solution. `int x, y = scanf("%d", &x);`, for example, reads *only* the `int` value, stores *only* error codes into the return value, and `scanf("%*[^\n]"); scanf("%*c");` reads and discards the remainder of the line *without any temporary variables needed*. – autistic Oct 09 '17 at 09:39
  • @Sebivor "*Out of curiousity, how would you read a single `int` value, encoded as a sequence of decimal digits?*" I wouldn't. In fact, in 10 years of writing programs, I've never needed to do that once. – melpomene Oct 09 '17 at 16:57
  • @melpomene Are you sure you've never had to write code that translates a sequence of decimal digits, in ten years? That's not something you should brag about... If you use `sscanf(str, "%d", &val)`, `scanf("%d", &val)`, `atoi`, `strtol` or whatnot or you roll your own digit-parsing loop, you're doing exactly that. Look, there are two ways to look at this; you could *exclude `scanf` at all cost, because it's too complex to understand* or you could *read books and manuals to understand `scanf`* (as expected in order to avoid UB, since you're programming in C and not Javascript). – autistic Oct 10 '17 at 11:12
  • @Sebivor Why not both? I already understand `scanf`. That's why I recommend against using it. You're somehow assuming I haven't read any *books or manuals*, which is a bit rude. My reasons for avoiding `scanf` have nothing to do with it being too complex to understand. – melpomene Oct 10 '17 at 19:28
  • @melpomene I've *never* read a programming book in my life, just bought a few and didn't even bother to look inside. i am still learning somehow :D – Ahmed Can Unbay Oct 10 '17 at 19:33
  • i don't mean anything rude by the way, I did not even read the chat that well. @melpomene – Ahmed Can Unbay Oct 10 '17 at 19:36
  • @melpomene Well, if you read books, you'll quickly realise that `scanf`, when used correctly in the right context (like all useful tools in C, and like it's introduced in common C books), `scanf` is better at doing a select few things than any of the other tools. You should *always* choose the most appropriate tool for the task, and if that means you're reading an *`unsigned int`* from `stdin`, then `scanf` is your key; nothing else will do that without introducing extra variables (at the least), for example. – autistic Oct 15 '17 at 15:13
  • @turmuka You'll still learn. Whether you're learning C as a standardised language that allows you to write portable code, or whether you're learning whatever your system calls "C" which "behaves differently" from the standardised language, you'll learn *some* programming language. That language might not be standard C. Without reading a book, based on my experience, you'd probably have a 1% chance. – autistic Oct 15 '17 at 15:22
  • @melpomene I assume you'd use `fgets`, here... When you use `fgets`, if the end of the *buffer* is reached before a newline is encountered, reading will stop there and the buffer won't contain a newline. Thus, you must parse the line *again* to determine whether or not a newline is present, and if no newline is present then... what do you suppose would need to happen to ensure `stdin` is in a sensible state? I recommend one of those *read and discard up until a newline* functions, of which your best option is actually also `scanf`, funnily enough. Again, no variables required! – autistic Oct 19 '17 at 03:20

0 Answers0