Freesnöw
Freesnöw

Reputation: 32143

'fgets' runs after 'printf'

I'm slowly learning C. I read this page about input and output dealing with strings here: http://www.cprogramming.com/tutorial/c/lesson9.html

In the last code example, fgets is used to get and assign the input to a variable to the char array name. I tried implementing something similar in my own program.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

/* This is my very first C program! */

bool test=true;

/* Function Prototypes */

int mult(int x, int y);

/* Structures */

struct Person {
    int age;
    char name[256];
};

/* Complicated Array ;P */

struct Person *FirstPeriod[22];
char FakeString[100];

void PracticeStrings()
{
    int i;
    fgets(FirstPeriod[0]->name, 256, stdin);
    for (i=0;i<256;i++)
    {
            if (FirstPeriod[0]->name[i]=='\n')
                FirstPeriod[0]->name[i]='\0';
    }
    printf("\n\nHello Student 0: %s",FirstPeriod[0]->name);
}

int main()
{
    struct Person DadeLamkins;
    DadeLamkins.age=16;
    int numb;
    int x;
    int *numb_address=&numb;
    numb_address=malloc(sizeof(*numb_address));

    FirstPeriod[0]=&DadeLamkins;

    if (true)
        printf("-__- \n\n");

    printf("Please enter a number: ");
    scanf("%d", &numb);
    switch (numb) {
        case 0:
            printf("Dude, 0 is lame...\n");
            break;
        case 7:
            printf("Dude, 7 is my favorite number!\n");
            break;
        default:
            printf("You entered %d\n", numb);
            break;
    }
    for (x=0;x<numb+1;x++) {
        printf("\n::# %d",mult(x,2));
    }
    printf("\n\n%d",numb_address);
    free(numb_address);
    numb_address=0;
    PracticeStrings();
    getchar();
    return 0;
}

int mult (int x, int y)
{
    return x*y;
}

The PracticeStrings function on line 26 is the issue currently. When I compile, it displays Hello Student 0: before accepting the input (from fgets). I'm using Code::Blocks to compile.

Any help would be appreciated!

Edit...

Hahaha, yes, I understand that my program is inefficient and very silly. As you can tell, it doesn't really accomplish much. It is mostly just something to shove what I'm currently learning and try to apply things without actually rewriting the code examples (what do I learn if I copy word for word?). Anyways, thanks for the help! I guess that does make sense! It is too bad that my tutorials didn't mention that, I'm sure it is something that just takes a little bit of a higher understanding. I'm sure that the tutorial writer didn't expect anyone to mix the functions in the way I did.

Thanks a ton guys! Hopefully I can get used to this. I've done lots of scripting and plenty in the .net languages, hopefully I can add C to this list :)

Upvotes: 3

Views: 1832

Answers (2)

Andrew Edgecombe
Andrew Edgecombe

Reputation: 40372

I think your issue is due to the behavior of your console, and your scanf() call.

The default setting for your console is probably line buffering. That means that nothing you type on your terminal is sent to stdin until after you have hit the enter key.

However, your call to scanf() (in main()) is only grabbing the integer that you've typed - not the trailing carriage return. Your carriage return is still sitting, unread, in stdin until the fgets() call in line 26. One way around that is to get scanf() to consume the trailing carriage return too:

scanf("%d%*c", &numb);
Which reads the integer from stdin into &numb, and reads (and discards) an extra character.

This all hilights one of the big problems with the use of scanf(), which is how to make it cope in the event that you get a string that you weren't expecting. A safer way is to use a combination of fgets() and sscanf(). The former will let you read a string from a file (as you've done), and the latter will run a formatting string over it. eg.


    char temp[20];
    fgets(temp, 20, stdin);
    sscanf(temp, "%d", &numb);

Upvotes: 0

Morpfh
Morpfh

Reputation: 4093

It is because when you read the number:

scanf("%d", &numb);

stdin still has \n left in the buffer. So when you call PracticeStrings() and subsequently:

fgets(FirstPeriod[0]->name, 256, stdin);

You read \n and end up with

FirstPeriod[0]->name[i] == '\0';

Further, as you are learning, learn to validate :)

I.e.:

if ((foo = malloc(blah)) == NULL) {
    ... err ...

And even more critical:

if (scanf(..) != number_of_items_i_want) {
    ... did not get a number, or what ever I wanted ...

etc.

Upvotes: 4

Related Questions