tags:

views:

87

answers:

5

How would I go about reading a string from stdin and formatting as such to stdout?

For example: If I receive someone's name: John Doe 03 17

I want to create user name for him as such: jd0317

Although it can change to for someone with a middle name: Jane B. Doe 05 18

Then it would be: jbd0518

I assume you would read the line and then when you reach a space, you would store that part of the name in an array and chop off the rest of it which you won't need. I would keep reading until CTRL^D was read from stdin which would represent the EOF.

Would I just use scanf in a loop or getchar?

A: 

To read the data in use either fgets() with stdin or getchar() in a loop - or see if your library has a getline().

You can then split the resulting string with strtok(), or if that seems too complicated (it is at first sight), you coudl split the input yourself as you read it with getchar() - just detect the spaces and copy the values yourself.

Martin Beckett
A: 

You can use fgets in a loop until a NULL is returned (which happens if EOF is reached).
Using it you can read a complete line from the input into a char array.

Next you can parse the line looking for spaces and every time you see a space, see if the previous chunk was non-numeric if yes copy its first char to the result. If it was numeric copy its digits to the result by making them char.

codaddict
A: 

You could use getchar in a loop and use EOF or newline as the loop terminating condition. The moment you read a character enter that into an array and ignore other characters till a space, then store the character next to space in your array and repeat the ignoring characters stuff till you reach the next space.

But, you need to take care of numbers as you seem to want to store all the numbers as is. For this you can compare the character entered with the ASCII values of numbers between 1 and 9 to see if it is a letter or number and store all the numbers. You may want to do this only if the character entered immediately after the space is a number as your question seem to suggests this requirement.

Also, you may have to do some error checks as your functionality demands. Please don't forget to check for array bounds in the array where you are storing this.

This is just my basic suggestion. Hope this helps.

Jay
+2  A: 

I would use 'fgets()' to get a line, and then process that to make the name:

#include <string.h>
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char line[512];
    if (fgets(line, sizeof(line), stdin) != 0)
    {
        char  name[16];
        char *dst = name;
        char *end = name + sizeof(name) - 1;
        char *src = line;
        while (*src != '\0')
        {
           char  c;
           while ((c = *src++) != '\0' && isspace(c))
               ;
           if (isalpha(c))
           {
               if (dst < end)
                   *dst++ = tolower(c);
               while ((c = *src++) != '\0' && !isspace(c))
                   ;
           }
           else if (isdigit(c))
           {
               while (dst < end && isdigit(c))
               {
                    *dst++ = c;
                    c = *src++;
               }
           }
        }
        *src = '\0';
        puts(name);
    }
    return 0;
}

Given the input 'John Doe 03 17' outputs 'jd0317'; given the input "Jane B. Doe 05 18" generates "jbd0518".

Jonathan Leffler
To intercept the CTRL^D to close stdin, could I just change the '\0' to EOF? So when you push ctrl^d on the terminal, shouldn't that print out the corresponding username?
As written, the code reads one line and stops - it doesn't care about EOF or not.You could extract the main body into a function that is called repeatedly (or replace the 'if (fgets...)' with 'while (fgets...)') to keep going until EOF. The program doesn't know how EOF is generated; I typed ^D but that is not seen by 'the program'. The Unix terminal driver interprets that as a request to 'return 0 bytes on next read' (subject to some conditions).
Jonathan Leffler
But I thought it was possible to use CTRL^D to close the stdin to therefore print stdout on the line after?
@ray2k: yes, more or less. Please see: http://stackoverflow.com/questions/358342/canonical-vs-non-canonical-terminal-input/358381#358381 for a lot more information about terminals and things like EOF (the EOF section is near the end of that answer).
Jonathan Leffler
A: 

To read an entire line, including spaces, you can use fgets in a loop until and EOF is encountered. Then, you can use either sscanf or strtok to get to the individual space separated elements of each line.

sscanf is usually the best choice if you already know how many tokens each line contains and their types. strtok enables you to get all tokens from a line even when you don't know how many tokens it has.

MAK