-1

I played a bit with strings and I came across such a situation, the idea is to delete the spaces in the word s2 and I just put the number 1 and it just works. it's not clear to me why. what happened here and what's going in the memory? Is it really a good solution ?

  char s2[]= " wo rl  d";
    char *h = s2;
    while(*h != '\0'){
        if(*h == ' '){
            *h=1;
        }
        h++;
    }
    printf("%s",s2);
Acorn
  • 24,970
  • 5
  • 40
  • 69
arthur
  • 43
  • 4
  • The literal `int` is implicitly converted to `char` (ASCII) so 1 is `Start of Header (SOH)` https://theasciicode.com.ar/ascii-control-characters/start-of-header-ascii-code-1.html. It is an unprintable character so that is why it appears to work. But is incorrect obviously. If you want to remove spaces in C++ use standard algorithms: https://stackoverflow.com/questions/83439/remove-spaces-from-stdstring-in-c – Resurrection Apr 08 '20 at 11:00
  • @Resurrection -- the `int` value 1 is converted to `char` without changing its value. The resulting value is 1. This has nothing to do with ASCII. It's only when you get around to displaying the contents of a `char` variable that you have to think about character encodings, and then, although ASCII is the most common, you can't simply assert that 1 is SOH; it doesn't have to be. – Pete Becker Apr 08 '20 at 12:52

2 Answers2

2

1 in ASCII table is unprintable character (start of heading - SOH). When printing it, your program will just skip over those (well, probably - ASCII is not guaranteed in any C++ program).

what's going in the memory?

In memory, you still have those 1 at every spot.
It looks like this:

1   119 111 1   114 108 1   1   100 0       // decimal values, assuming ASCII
SOH w   o   SOH r   l   SOH SOH d   NUL     // char representations

Is it really a good solution ?

Not really. char 1 might be printed differently on some systems. strlen() will return full length of string, including those SOH characters, rather than number of printed characters (which one might expect). Iterating over this string will yield weird values. In general, working with this string later will be a mess.
It kinda works, for now, but you should probably truly remove characters instead of just replacing them with unprintables.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • `strlen` doesn't care about character encodings. It simply counts the number of non-zero characters at the head of the string. That's always, by definition, the correct value. It may well differ from the number of characters that you see on your display, but that's not its job. – Pete Becker Apr 08 '20 at 12:54
  • @PeteBecker I suppose I should've called it "excepted value" rather than "correct". Edited now. – Yksisarvinen Apr 08 '20 at 13:30
  • No, if you "expect" `strlen` to tell you how many characters will be displayed, your expectation is wrong. `strlen` has nothing whatsoever to do with the display. There are many things that can go into C-style strings that do not result in a character being displayed when the string is copied to the console. For example, many consoles support [ANSI escape sequences](http://ascii-table.com/ansi-escape-sequences.php) which modify how and where characters are displayed. Writing `"\x1b[32m"` to such a console turns the foreground green, but doesn't display any characters. – Pete Becker Apr 08 '20 at 13:41
1

You are setting the value of all chars in s2 that are a space to the value 1, which is SOH in ASCII, a non-printable character (check this site for a table of all ASCII values). (*h dereferences the pointer, allowing you to change the value of the char it points to, and ints can be implicitly conerted to char).

It's certainly not a very clean solution, since you are wasting space with an unprintable char. Maybe do this instead:

std::string = "wo rl d";
remove_if(str.begin(), str.end(), isspace);
melk
  • 530
  • 3
  • 9