0

So, I'm working on this program and I've encountered a problem with scanf. I'm scanning the input from the user in the form of a string, however if the user just presses enter, scanf doesn't pick up on it and the cursor just moves on waiting for whatever specified input I programmed it to look for. Is there anyway I can skirt around this with like a comparison to 0 or 1, or do I need to go about this in another way? Yes, this is the same program from earlier and I thought to mention this in the other post I made, but I figured this was a different problem in itself so it deserved another post separate from my other problem earlier.

/* 
* Scott English
* CS 1412
* tconv
* 1/28/15
*/

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

FILE *
input_from_args(int argc, const char *argv[])
{
    if (argc == 1){
        return stdin;
    }
    else {
        return fopen(argv[1], "r");
    }
}

void
rot_13(FILE *src, FILE *dest)
{
    int c,j;

    while ((c = getc(src)) != EOF)
    {
    if(c>= 'A' && c <= 'Z')
    {
        if((j = c + 13) <= 'Z') 
            c = j;
        else
        {
            j = c - 13;
            c = j;
        }
    }
    else if(c >= 'a' && c <= 'z')
    {
        if((j = c + 13) <= 'z')
            c = j;
        else
        {
            j = c - 13;
            c = j;
        }
    }
    else
    c = c;

    fprintf(dest, "%c", c);
    }
}

void
convert_all_upper(FILE *src, FILE *dest)
{
    int c;

    while ((c = fgetc(src)) != EOF) 
    {
        fprintf(dest, "%c", toupper(c));
    }
}

void
convert_all_lower(FILE *src, FILE *dest)
{
    int c;

    while ((c = fgetc(src)) != EOF) 
    {
        fprintf(dest, "%c", tolower(c));
    }
}

void
print_all(FILE *src, FILE *dest)
{
    int c;

    while ((c = fgetc(src)) != EOF) 
    {
        fprintf(dest, "%c", c);
    }
}


int
main(int argc, const char *argv[])
{

    char answer[4];

    FILE *src = input_from_args(argc, argv);
    FILE *dest = stdout;

    printf("Please enter which conversion -r -u -l\n"); 
    scanf("%s", answer);

    if (src == NULL)
    {
        fprintf(stderr, "%s: unable to open %s\n", argv [0], argv[1]);
        exit(EXIT_FAILURE);
    }

    else if (strcmp(answer,"-r") == 0)
    { 
        rot_13(src, dest);
    }   

    else if (strcmp(answer, "-u") == 0)
    {
        convert_all_upper(src, dest);
    }           

    else if (strcmp(answer, "-l") == 0)
    {
        convert_all_lower(src, dest);
    }

    else 
    {
        printf("%s: is unsupported\n", answer);
    }   
    fclose(src);

    return EXIT_SUCCESS;
}
Chris Loonam
  • 5,735
  • 6
  • 41
  • 63
Senglish
  • 115
  • 1
  • 3
  • 9
  • 1
    something like `answer[0] == '\n'` you mean? – Sourav Ghosh Feb 02 '15 at 07:52
  • yes, what I'm looking for is an if statement like the rest of them that takes the value of answer and compares it to a blank input. So if I run the program and hit enter, then after that point whatever I type, it will repeat back onto the screen for me. – Senglish Feb 02 '15 at 07:54
  • 1
    possible duplicate of [How do you allow spaces to be entered using scanf?](http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf) – n. m. could be an AI Feb 02 '15 at 07:55
  • yes but how would I use strcmp to compare the answer to a blank input? – Senglish Feb 02 '15 at 08:01
  • ROT13: `if(c>='A' && c<='Z') c='A'+(c-'A'+13)%26; else if(c>='a' && c<='z') c='a'+(c-'a'+13)%26;` – CiaPan Feb 02 '15 at 09:55

3 Answers3

1

ESTRAPOLATED FROM LINK

scanf stands for "scan formatted" and there's precious little less formatted than user-entered data. It's ideal if you have total control of the input data format but generally unsuitable for user input.

Use fgets() to get your input into a string and sscanf() to evaluate it.

A simple program to show you how to intercept the 'enter' key.

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

int main()
{
    char answer[4];
    memset(answer, 0x00, sizeof(answer));

    printf("Please enter which conversion -r -u -l\n");
    fgets (answer, sizeof(answer), stdin);

    if (strlen(answer) > 0)
    {
        if (answer[0] == '\n')
        {
            printf("Empty string and enter key pressed\n");
        }
        else
        {
            printf("Parameter %s", answer);
        }
    }


    return 0;
}
Community
  • 1
  • 1
LPs
  • 16,045
  • 8
  • 30
  • 61
1

I recommend using fgets:

fgets(answer, sizeof answer, stdin);

instead of scanf, since scanf skips over whitespace including newlines, and the user won't be able to get out of the input loop.

Jake
  • 2,106
  • 1
  • 24
  • 23
  • " scanf skips over whitespace" is true for `scanf("%s", answer)` but it depends on the format - many formats specify `scanf()` to skip over whitespace, but certainly not all. – chux - Reinstate Monica Feb 02 '15 at 21:51
1

"if the user just presses enter, scanf doesn't pick up on it" -->
scanf("%s", answer) is just beginning.

The "%s" specifies scanf() to scan 3 things:
1) Scan in and toss all leading white-space including '\n', ' ', '\t' and a few others.
2) Scan in and save an unlimited number of non-white-space char to answer. Append a terminating '\0' when done.
3) Upon scanning a white-space again, put that char back into stdin for later reading.

So when a user enters Enter or '\n', scanf("%s", answer) is still in step 1.

As a rule: mixing scanf() with fgets()/getc() is problematic. Further recommend against using scanf() for just about all applications. Consider:

// char answer[4];
// scanf("%s", answer);

char answer[4+1];
if (fgets(answer, sizeof answer, stdin) == NULL) return 1;  // stdin closed

// now remove the potential trailing '\n`.
size_t len = strlen(answer);
if (len > 0 && answer[len-1] == '\n') answer[--len] = 0;
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • ok, but I'm not wanting to remove the '\n' inputed by the user, I'm wanting to detect the '\n' so I can tell the program to do nothing and just print out what ever the user types to the screen after they type nothing and press enter. – Senglish Feb 02 '15 at 21:28
  • @Senglish Then remove the last 2 code line and test for `if (answer[0] == '\n')` – chux - Reinstate Monica Feb 02 '15 at 21:29
  • @Senglish Or leave in the 2 lines of code and test `if (answer[0] == '\0')`. This will allow your other test like `if (strcmp(answer,"-r") == 0)` – chux - Reinstate Monica Feb 02 '15 at 21:31
  • Ok, thanks for the info! I have to do my other program which is similar to this one so I will keep this in mind! Thanks a bunch! – Senglish Feb 02 '15 at 21:39