Simple Input Will Not Work

I thought I once posted this but apparently not. The commented code works, but the C code does not. So what is going wrong? :angry:
/*
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::string;

int main()
{
    string first_name, last_name;
    cout << "Enter first and last name, and then press enter: ";
    cin >> first_name >> last_name;
    cout << "Hello " << first_name << ' ' << last_name << ".\n";
}
*/ 

#include <stdio.h>

int main()
{
    char first_name [15], last_name [15], c1, c2;
    printf ("Enter user first and last name, and then press enter: ");
    scanf_s ("%s %s", &first_name, &last_name, &c1, &c2);
    printf ("Hello %s %s.\n", &first_name, &last_name, &c1, &c2); 
} 

Comments

  • I tried to compile your C code on Dev-C++. It gaves me an error : scanf_s undclared :( . So i change just to scanf and it works perfectly.

    Also i read that scanf_s() is not a drop-in replacement for scanf(). You need to include a buffer size when the input parameter is a character or string.
    Example:
    char a; 
     
    scanf("%c", &a); 
    scanf_s("%c", &a, 1);  /* equivalent to the above */
    

    Read: Information about scanf_s
  • I get warnings when I use [icode] scanf(); [/icode] so I use [icode] scanf_s(); [/icode]. Your code should only work if you where using an integer data type. :icon_wink:
  • MyPianoSucks is correct - you need to pass the size immediately after the input pointer.
    I get warnings when I use [icode] scanf(); [/icode] so I use [icode] scanf_s(); [/icode]. Your code should only work if you where using an integer data type. :icon_wink:
    No, MyPianoSucks' code is fine - you should follow the link he provided and actually read the function's documentation.
  • This is all I am get out of that. :(
  • Never Mind! :$
    #include <stdio.h>
    
    int main()
    {
        char first_name [15], last_name [15];
        printf ("Enter user first and last name, and then press enter: ");
        scanf_s ("%15s %15s", &first_name, 15, &last_name, 15);
        printf ("Hello %s %s.\n", first_name, last_name);
    }
    
  • This is all I am get out of that. :(

    you get that because you declared a char and not a string ;)
  • I get warnings when I use scanf(); so I use scanf_s();
    I wont really suggest the use of scanf_s, it is microsoft specific, and you will have a hard time keeping it portable. In fact, MSVC++ is the only compiler that has deprecated scanf(), to stop the warnings you may use :
    #define _CRT_SECURE_NO_DEPRECATE
    
    If I were you I would still b using scanf, or better still use a combination of fgets and sscanf.
    Or to stop this particular warning I think this should do...
    #pragma warning(disable: 4996)
    
    Your code should only work if you where using an integer data type
    What? Didn't get you...
  • Do you mean Microsoft specific as in it will only run on Windows Operating Systems? I do not plan on programming for any other OS, but you do have a point with some great info! However both warning solution's above get rid of the warning, but the program does not work.
  • If you want standard C, this is it:
    #include <stdio.h>
    
    int main()
    {
        char first_name [15], last_name [15], c1, c2;
        printf ("Enter first and last names, and two single char's, with a single space between each, and then press enter: ");
        scanf ("%s %s %c %c", first_name, last_name, &c1, &c2);
        printf ("Hello %s %s %c %c.\n", first_name, last_name, c1, c2); 
    
        return 0;
    }
    

    With scanf(), you need an address, (because you are changing the value of a variable), but the name of a string array IS a constant address, so no & (memory of) operator, is needed for strings. For single char's and any numbers, yes - needed then.

    When printing, you never need the & operator, since printf() is not changing the variable, just printing it.

    Is that you in your avatar, playing the bagpipe?
  • Yes that is Me in the avatar playing a 40 year old set of Great Highland Bagpipes. There older then me. Hand Made in Glasgow Scotland by R.G Hardie the Maker's of the world's finest bagpipes. To keep this programming related I will add that there not CNC Lathe turned! Some are.
  • That's great! Keeping the traditions alive. I hope the photographer got some great shots of it.

    Now laddie, do ye nay ken my wee bit o' code? ;)

    You know what the joke is about the pipers, and why they always play whilst on the move?

    Harder to hit a moving target! :icon_mrgreen:

    It's a bit strange that the pipes have brought out the martial spirit, as much as it has. There's a country in the Middle East that was introduced to them some years back (maybe WWII), and they're now very fond of them.
  • ...but the program does not work
    Which program doesn't work??
    Your last posted program
    #include <stdio.h>
    
    int main()
    {
        char first_name [15], last_name [15];
        printf ("Enter user first and last name, and then press enter: ");
        scanf_s ("%15s %15s", &first_name, 15, &last_name, 15);
        printf ("Hello %s %s.\n", first_name, last_name);
    }
    
    does work, though with some bugs in it.
    The string format doesn't consider space for the NUL character, it should be
    scanf_s ("%14s %14s", &first_name, 15, &last_name, 15);
    
    And also you should check the return value of the input functions you use.
  • I hate to bring up an old subject, but it was never answered. I want to know why cin does what scanf_s should be doing.
    #include <iostream>
    #include <stdio.h>
    using std::cin;
    
    int main()
    {
    	char question;
    	do
    	{
    		printf ("Would you like to repeat this? (y/n): ");
    		//cin >> question;
    		scanf_s ("%1c", &question);// I use scanf_s because of warning C4996: With or without it _s cin gives the desired result. 
    	}
    	while (question != 'n');
    }
    
  • scanf_s requires a third parameter -- buffer size. Why do you use "%1c" instead of just "%c"? Without the length specifier %c only allows 1 character.

    scanf_s ("%c", &question,1)
    I use scanf_s because of warning C4996

    You can disable that warning -- probably compiler dependent but Visual Studio C++ is like this:
    [icode]#pragma warning(disable: 4996)[/icode]
  • I do use %c it's just that I was trying see if it would help, so I just forgot to change it back. disabling the warning only gets rid of the warning it does not fix the problem. I will look up the parameters for scanf_s and see what I get.
  • Ok I just looked up scanf_s parameters and all that is, is a big run around wild goose chase. I don't care about if it is NULL or not.
  • Are you looking for
    scanf(" %c",&myCharVariable);
    

    Note the space before the %c, in the above format parameter.

    I don't use C++, so describing it in terms of cin is meaningless.
  • did you see this thread?
    disabling the warning only gets rid of the warning it does not fix the problem

    Depends -- I don't consider it to be a problem if you know what you're doing.
  • Can you see to problem yet I don't want what is going on in the prompt to happen.
  • %c only removes one character from the keyboard buffer -- the Enter key is still there. So the next time scanf_s is called it will get the '\n' from the keyboard buffer.

    Instead of getting just a single character try getting an entire string
    char c[3];
    do {
        scanf_s("%s", c, 3);
    } while( c[0] != 'n' );
    
  • #include <stdio.h>
    
    int main(void) {
       char a,i;
    
       do {
          printf("Would you like to repeat? (y/n): ");
          scanf("%c",&a);
          while((i=getchar()) != '\n');
       }while(a != 'n');
    
      return 0;
    }
    
  • Thanks guys I feel like a new paradigm. :icon_mrgreen:
  • Entirely welcome.

    I'd keep that while loop handy - it's an "industrial strength" input stream cleaner. ;)
  • Ok so what would you need to do in order to get the loop to repeat only when y is used, and exit when n is used. Then again I could just print out Would you like to repeat? (whatever/n): , but that would be rather strange don't you think.
  • Ok so what would you need to do in order to get the loop to repeat only when y is used, and exit when n is used. Then again I could just print out Would you like to repeat? (whatever/n): , but that would be rather strange don't you think.

    So instead of this: (how it is now)
    Would you like to repeat? (y/n): y
    Would you like to repeat? (y/n): y
    Would you like to repeat? (y/n): n
    

    You want:
    Would you like to repeat? (y/n): y
    Would you like to repeat? (y/n): y
    Would you like to repeat? (y/n): <any key at all except y>
    

    Right?

    Change the test to while(a == 'y').
  • I only want it to pay attention to y and n. The only thing that comes to mind is <conio.h>, but I just don't know if that is appropriate. The below example console prompt is irritating.

    Pretend A Game Has Been Played
    Would you like to play again? (y/n): as
    Pretend A Game Has Been Played
    Would you like to play again? (y/n): asdf
    Pretend A Game Has Been Played
    Would you like to play again? (y/n): y
    Pretend A Game Has Been Played
    Would you like to play again? (y/n): n
    Press any key to continue . . .
  • It's a logic problem. If you want it to ignore any other input except y or n, that's OK, but once that ignore state is initiated, without a prompt and a chance to change that state back (there would now be NO PROMPT, either), how could that be done?

    You can't get the program to ignore input BUT somehow know when you intend to enter a y or n some time in the future. You have to give the program some keystroke or count, or SOMETHING of a message, to have it return from the ignore state, to giving the user a prompt again.

    But right now I'm baking in the heat, so take this with a grain of very warm, salt.

    conio.h won't help in this matter. It will give you unbuffered input (as can the Windows API), but it won't solve the logic problem.
  • I have dabbled with the logic side of it before encapsulating it in infinite loops with no luck. Do you think buffered input with an if else structure might do the trick. Still seems like that could be finicky though.
  • What? I don't understand the last two comments.


    Just use getline instead of a single character or if y/n is not entered, loop and discard input until a newline is encountered.
  • SMJ, did you try this?
    #include <stdio.h>
    
    int main(void) {
       char a,i;
    
       do {
          printf("Would you like to repeat? (y/n): ");
          scanf("%c",&a);
          while((i=getchar()) != '\n');
       }while(a != 'n');
    
      return 0;
    }
    

    It removes all the chars from the input stream, with every entry. Only the first one is acted upon. That is what you showed here:
    Would you like to play again? (y/n): as
    Pretend A Game Has Been Played
    Would you like to play again? (y/n): asdf
    Pretend A Game Has Been Played
    Would you like to play again? (y/n): y
    Pretend A Game Has Been Played
    Would you like to play again? (y/n): n

    I thought that's what you wanted.
Sign In or Register to comment.