0

I'm pretty new to C. Writing in Visual Studio 2015, I'm trying to safely prompt a user for a string by using fgets. I want to use fgets to get the string, check if the string is too long, and reprompt the user if it is until they enter a good string. Here is my code

/*
* Nick Gilbert
* COS317 Lab 2 Task 2
*/
#include "stdafx.h"
int main()
{
    char str[10];
    int isValid = 0;
    while (isValid == 0) {
        printf("Please enter a password: ");
        fgets(str, 10, stdin);
        if (strlen(str) == 9 && str[8] != '\n') { //http://stackoverflow.com/questions/21691843/how-to-correctly-input-a-string-in-c
            printf("Error! String is too long\n\n");
            memset(&str[0], 0, sizeof(str));
        }
        else {
            printf(str);
            isValid = 1;
        }
    }
    printf("Press 'Enter' to continue...");
    getchar();
}

However, when I run this and enter a bad string, the excess characters get fed into the next fgets automatically!

enter image description here

How can I fix this to do what I want it to do?

5
  • 2
    printf(str); --> printf("%s\n", str); Commented Feb 1, 2016 at 16:59
  • Best Advice - Quit Visual Studio to learn C! Start with something like CodeBlocks on Windows. Commented Feb 1, 2016 at 16:59
  • this answer may be useful. Commented Feb 1, 2016 at 17:16
  • Checking for overly-long input is a good idea. The problem here is that, in effect, fgets is already doing that for you, and what it does with the overly-long input is, it leaves it on the input stream for somebody else to read. When you call fgets(str, 10, stdin) you are saying "read characters from stdin into str until you see a newline or you have read 10 characters, whichever comes first". Commented Feb 1, 2016 at 20:58
  • the reason it fails is because of your str[8] != \n. you are insisting that the 7th character is a newline. Commented Feb 1, 2016 at 21:00

2 Answers 2

1

If the string read in by fgets doesn't end with a newline, call fgets in a loop until it does, then prompt the user again.

    if (strlen(str) > 0 && str[strlen(str)-1] != '\n') {
        printf("Error! String is too long\n\n");
        do {
            fgets(str, 10, stdin);
        } while (strlen(str) > 0 && str[strlen(str)-1] != '\n') {
    }

Also, never pass a variable at the first argument to printf, particularly if the contents of that variable comes from user entered data. Doing so can lead to a format string vulnerability.

Sign up to request clarification or add additional context in comments.

1 Comment

Format string vulnerabilties are actually what part 3 of this lab addresses haha
0

Try this:

#include "stdafx.h"
int main()
{
    char str[10];
    int isValid = 0;
    while (isValid == 0) {
        printf("Please enter a password: ");
        fgets(str, str, stdin);
        if (strlen(str) == 9 && str[8] != '\n') { //http://stackoverflow.com/questions/21691843/how-to-correctly-input-a-string-in-c
            printf("Error! String is too long\n\n");
            memset(str, 0, sizeof(str));
        }
        else {
            printf("%s",str);
            isValid = 1;
        }
    }
    printf("Press 'Enter' to continue...");
    getchar();
}

In addition:

While using memset() you can directly use the array_name rather &array_name[0].

1 Comment

Rather than 10,9,8 in fgets(str, 10, stdin); if (strlen(str) == 9 && str[8] ..., consider fgets(str, sizeof str, stdin); if (strlen(str) + 1 == sizeof str && str[sizeof str - 2]. Just like code used well in memset(str, 0, sizeof(str));.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.