0

I want to read a string from stdin, save it in a array, convert so it matches the specified test(s):

expected = "45 76 65 72 79 20"

I've already tried every solution I could find since Friday, except strtol which I don't understand how to use.

    char input;
    char *buffer = NULL;
    char chunk[2];
    size_t stringLength = 0;
    int n = 0;

    while(fgets(chunk, 2, stdin) != NULL){
        stringLength += strlen(chunk);
    }
    rewind(stdin);

    buffer = (char *) malloc(stringLength + 1);
    if (buffer == NULL)
        exit(EXIT_FAILURE);

    while(scanf("%c", &input) == 1) {
        snprintf(buffer+n, 2, "%c", input); 
        n += strlen(chunk);
    }

    //code to convert char array buffer to array of hex separated by spaces

Example text received from stdin = "Every P";

String I need to output to pass the example test: = "45 76 65 72 79 20 50";

Please tell me if I'm making any mistakes, I've been learning how to write C-code for 1 1/2 months.

Thanks in advance!

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Richard
  • 27
  • 6
  • Google the `itoa` function. – 500 - Internal Server Error Oct 28 '19 at 18:46
  • 1
    `rewind(stdin);` Is that possible? – 001 Oct 28 '19 at 18:50
  • 2
    `sprintf(buf, "%02x", 'G')` – pmg Oct 28 '19 at 18:52
  • [There are some good threads on the topic of rewind(stdin)](https://stackoverflow.com/questions/16672672/can-fseekstdin-1-seek-set-or-rewindstdin-be-used-to-flush-the-input-buffer-i) – jhelphenstine Oct 28 '19 at 18:55
  • Is your code expected to map "Every P" to "45 76 65 72 79 20 50"? – jhelphenstine Oct 28 '19 at 18:56
  • @jhelphenstine if you mean print the string "45 76 65 72 79 20 50", then yes. `std::string expect = "45 76 65 72 79 20 50";` @pmg I tried to write the chars with `printf("%02x ", buffer);`. That did print the letters and the spaces, but it did'nt pass the test. I don't know why, but I think it has to do with formatting? – Richard Oct 28 '19 at 22:29
  • @Richard: with `printf("%02x ", buffer);` there will be a space after every element (`output == "45 76 65 72 79 20 50 "`). You need to get rid of that last space (or, maybe better, avoid it altogether) – pmg Oct 29 '19 at 13:12
  • Does this answer your question? [Convert a character digit to the corresponding integer in C](https://stackoverflow.com/questions/628761/convert-a-character-digit-to-the-corresponding-integer-in-c) – dandan78 Oct 29 '19 at 13:29

1 Answers1

1

AFAIK, rewind(stdin) is questionable. A different option is to use realloc to grow your array one char at a time.

int c;
char *s = NULL;
int char_count = 0;

// Read one char at a time, ignoring new line
while (EOF != (c = getc(stdin))) {
    // Ignore CR (i.e. Windows)
    if ('\r' == c) continue;
    // Consume the newline but don't add to buffer
    if ('\n' == c) break;
    // Grow array by 1 char (acts like malloc if pointer is NULL)
    s = realloc(s, ++char_count);
    // TODO handle error if (s == NULL) 
    // Append to array
    s[char_count - 1] = (char)c;
}

// Create the buffer for the hex string
// 3 chars for each letter -> 2 chars for hex + 1 for space
// First one does not get a space but we can use the extra +1 for \0
char *hex = malloc(char_count * 3);
// TODO handle error if (hex == NULL)
// Create a temporary pointer that we can increment while "hex" remains unchanged
char *temp = hex;
for (int i = 0; i < char_count; i++) {
    // No space on first char
    if (i == 0) {
        sprintf(temp, "%02X", s[i]);
        temp += 2;
    }
    else {
        sprintf(temp, " %02X", s[i]);
        temp += 3;
    }
}
*temp = '\0';

printf("%s\n", hex);

// Cleanup
free(s);
free(hex);

Input: Every P
Output: 45 76 65 72 79 20 50


If all you want to do is reprint stdin as hex, there's no need for any buffers at all:

int c;
int char_count = 0;

// Read one char at a time and print as hex
while (EOF != (c = getc(stdin))) {
    // No space on first char
    if (0 == char_count++) {
        printf("%02X", c);
    }
    else {
        printf(" %02X", c);
    }
}
puts("");  // If you need a newline at the end
001
  • 13,291
  • 5
  • 35
  • 66
  • I will try this as fast as I get the time tomorrow! Thank you. By the way, is this solution safe against buffer overflow? I will need to make one slight modification, and that is linefeed/`'\n'` should print `0a`. – Richard Oct 28 '19 at 22:49
  • Why would I ignore `\r`? I would like to include `\n` and `\t` (tab) – Richard Oct 29 '19 at 11:52
  • @Richard You can just remove that line. Also, if all you are doing is taking the input and printing it in hex, there's no need for any buffers at all. Just read a char from `stdin`, then print in hex to `stdout`. – 001 Oct 29 '19 at 12:56