Take the tour ×

I am getting a junk character to be output at the very end of some text that I read in:

hum 1345342342 ~Users/Documents ecabd459 //line that was read in from stdin
event action: hum_?
event timestamp: 1345342342
event path: ~Users/Documents
event hash: ecabd459

At the end of the event action value there is a '_?' garbage character that is output as well. That can be rectified by setting the variable's last position to the null terminator (event.action[3] = '\0') which is all well and good, but I am perplexed by the fact that the other char array event.hash does not exhibit this type of behavior. I am creating/printing them in an identical manner, yet hash does not behave the same.

Note: I was considering maybe this was due to the hash value being followed strictly by a newline character(which I get rid of by the way), so I tested my program with re-ordered input to no avail (that is, added an additional space and word after the hash value's position on the line).

The relevant code is below:

struct Event{
    char action[4];
    long timestamp;
    char* path;
    char hash[9];

// parse line and return an Event struct
struct Event parseLineIntoEvent(char* line) {
    struct Event event;
    char* lineSegment;

    int i = 0;
    lineSegment = strtok(line, " ");
    while (lineSegment != NULL) {
        if (i > 3) {
            printf("WARNING: input format error!\n");
        if (i == 0)
            strncpy(event.action, lineSegment, sizeof(event.action)-1);
        else if(i == 1)
            event.timestamp = atoi(lineSegment);
        else if(i == 2) {
            event.path = malloc(sizeof(lineSegment));
            strcpy(event.path, lineSegment);
        } else if(i == 3)
            strncpy(event.hash, lineSegment, sizeof(event.hash)-1);
        lineSegment = strtok(NULL, " ");
    } // while
    return event;
} // parseLineIntoEvent()

    printf("%s\n",line); //prints original line that was read in from stdin
    struct Event event = parseLineIntoEvent(line);
    printf("event action: %s\n", event.action);
    printf("event timestamp: %lu\n", event.timestamp);
    printf("event path: %s\n", event.path);
    printf("event hash: %s\n", event.hash);
    return 0;

EDIT: I read in a line with this function, which gets rid of the newline character:

// read in line from stdin, eliminating newline character if present
char* getLineFromStdin() {
    char *text;
    int textSize = 50*sizeof(char);
    text = malloc(textSize);

    if ( fgets(text, textSize, stdin) != NULL ) {
        char *newline = strchr(text, '\n'); // search for newline character
        if ( newline != NULL ) {
            *newline = '\0'; // overwrite trailing newline
    return text;

Thanks in advance!

share|improve this question
How do you get rid of the newline? –  pmg Jan 9 '12 at 10:55
Please see the edit to my question. Thanks. –  Stunner Jan 9 '12 at 10:58
add comment

4 Answers

up vote 1 down vote accepted


You got unlucky. hash[8] may have gotten a '\0' by sheer (bad-)luck.

Try setting it to something "random" before your strtok loop

    int i = 0;
    event.hash[8] = '_';             /* forcing good-luck */
    lineSegment = strtok(line, " ");
    while (lineSegment != NULL) {
share|improve this answer
Yeah, now I am getting: event hash: ecabd459_ This is because event.hash was set to all '_' characters and I didn't overwrite the last one, correct? –  Stunner Jan 9 '12 at 11:11
Neither event.action nor event.hash were initialized, so they happen to contain garbage. In the case of event.action that garbage makes it not a string (it's UB to print it with "%s") and printf accesses memory areas that it shouldn't (event.action[4] and more). By setting event.hash[8] to '_' the same happens to this variable. Unluckly, the unexistent event.hash[9] appears to be a '\0'. –  pmg Jan 9 '12 at 11:18
add comment

This is a mistake:

event.path = malloc(sizeof(lineSegment));

will return the sizeof(char*), when you require the length plus one for terminating NULL character:

event.path = malloc(sizeof(char) * (strlen(lineSegment) + 1));

To avoid having to insert null string terminators into action and hash you could initialise event:

struct Event event = { 0 };
share|improve this answer
Note that sizeof(char) == 1 is explicitly guaranteed by the C standard. –  Dietrich Epp Jan 9 '12 at 11:02
Thanks for those tips. Worked well and that struct initialization tip is a very elegant fix to my problem. Have any ideas for the discrepancy I am witnessing? –  Stunner Jan 9 '12 at 11:03
@Stunner, sorry, what is the discrepancy? –  hmjd Jan 9 '12 at 11:06
@DietrichEpp, thanks. –  hmjd Jan 9 '12 at 11:06
@hmjd I am getting junk characters after the output for event.action, but not event.hash which are constructed in the same way, only difference is the sizes differ. –  Stunner Jan 9 '12 at 11:09
show 3 more comments

From the Linux manual page:

placed in dest will not be null-terminated.

When doing strncpy you have to make sure the destination string is properly terminated.

Change the setting of the event.action field:

if (i == 0)
    event.action[sizeof(event.action)-1] = '\0';
share|improve this answer
Thanks for the explanation and the nice way of fixing the issue, but why doesn't the same thing happen to the hash character array I did the same thing with? I use strncpy with that too... –  Stunner Jan 9 '12 at 11:00
@Stunner Yes, it applies to all calls to strncpy; If you are unsure, manually terminate the string. –  Joachim Pileborg Jan 9 '12 at 11:05
I'd omit the -1 from the size passed to strncpy. It doesn't matter much, because whether or not strncpy writes the last character, it will be overwritten by '\0'. But in general, passing sizeof(buf) to strnxxx functions is a good pattern. –  ugoren Jan 9 '12 at 12:03
add comment

This is because, the string "num" takes only three elements from the 4 element character array Event.action and the fourth element will stay unset. Because nothing has been set to the Event.action array element it will point to random memory location which has some random value stored. When you printf this character array it will print all of the elements instead of those pointing to valid data. This causes the garbage character to show up.

share|improve this answer
add comment

Your Answer


