gets() problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Barbosapt
    New Member
    • Jan 2008
    • 6

    #1

    gets() problem

    I have this global variable:
    Code:
    ...
    typedef struct{
    	int numero;
    	char nome[200];
    	char morada[200];
    	int contacto;
    } Cliente;
    Cliente clientes[2000];
    ...
    and this part of code:
    Code:
    void adiccionarCliente(){
    	char nomeCliente[200];
    	char moradaCliente[200];
    	int contactoCliente=0;
    
    	
    	printf("Introduza o nome do cliente:\n");
    	gets(nomeCliente);
    	strcpy(clientes[numeroCliente].nome, nomeCliente);
    ....
    }
    But when i run the program it just skips that gets(nomeClient e) and dont ask me for a nomeCliente.
    Sorry about my variable aren't in english.
    If you could help i would be gratefull.
    Thank you, Barbosa.
    Last edited by Barbosapt; Jan 10 '08, 02:23 PM. Reason: wrong size on the Cliente.nome
  • Savage
    Recognized Expert Top Contributor
    • Feb 2007
    • 1759

    #2
    It jumps both printf and gets?
    Have you tried flushing the streams?

    Comment

    • Barbosapt
      New Member
      • Jan 2008
      • 6

      #3
      Originally posted by Savage
      It jumps both printf and gets?
      Have you tried flushing the streams?
      only skips gets...and yes same problem even with flush

      Comment

      • Barbosapt
        New Member
        • Jan 2008
        • 6

        #4
        I have this after:
        Code:
        ...
        printf("Introduza a morada do cliente:\n");
        	gets(moradaCliente);
        	strcpy(clientes[numeroCliente].morada, moradaCliente);
        ...
        and it works...

        Comment

        • oler1s
          Recognized Expert Contributor
          • Aug 2007
          • 671

          #5
          Do not use gets. Use fgets.

          gets is kept around for historical uses, but it has been marked in documentation and on numerous forums as a "Do not use under any circumstances".

          gets has absolutely no bounds checking on input.

          Comment

          • Barbosapt
            New Member
            • Jan 2008
            • 6

            #6
            Code:
            ...
            printf("Introduza o nome do cliente:\n");
            	fgets(nomeCliente,200,stdin);
            	strcpy(clientes[numeroCliente].nome, nomeCliente);
            ...
            same problem
            Last edited by Barbosapt; Jan 10 '08, 04:04 PM. Reason: wrong tag

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              Can you post the code that calls adiccionarClien te() ??.

              I want to be sure you are calling the function in the first place because I compiled and ran your code using Visual Studio.NET 2005 and it worked.

              Comment

              • Barbosapt
                New Member
                • Jan 2008
                • 6

                #8
                Code:
                void menuPrincipal(){
                	int opcao=0;
                	printf("Escolha uma opccao:\n");
                	printf("1 Atender Cliente\n");
                	printf("2 Adiccionar Cliente\n");
                	printf("3 Editar Cliente\n");
                	printf("4 Estatisticas\n");
                	printf("0 Sair\n");
                	do {
                		scanf("%i",&opcao);
                		switch (opcao){
                			case 1:
                				atenderCliente();
                				break;
                			case 2:
                				adiccionarCliente();
                				break;
                			case 3:
                				editarCliente();
                				break;
                			/*case 4:
                				estatisticas();*/
                			case 0:
                				return;
                				break;
                			default:
                				printf("Erro: a opcao escolhida nao existe!\n");
                				printf("Escolha uma opcao:\n");
                				break;
                		}
                	} while(opcao<0||opcao>4);
                	return;
                }

                Comment

                • Savage
                  Recognized Expert Top Contributor
                  • Feb 2007
                  • 1759

                  #9
                  Both of these functions(gets and fgets) on error or EOF returns NULL.Have you checked to see whether this functions passes or not?

                  Also,I'm not suggesting that following is a good solution but it might work:

                  You said that next call to gets worked,so have you tried to put another call to gets(or fgets) after that one?

                  Comment

                  • oler1s
                    Recognized Expert Contributor
                    • Aug 2007
                    • 671

                    #10
                    Your code confirms my suspicions. Let’s work backwards, to see how one might diagnose the problem. Remember that information about the various C functions can be found in documentation, easily googled. Problem: fgets seems to be skipped.

                    What does fgets do? It extracts from the file stream (in your case stdin) until it reaches a newline. Then it returns. So perhaps fgets isn’t being skipped, but is returning right away. Why would it do that? Perhaps because there is something already in stdin. Since it’s returning right away, it stands to reason there is a newline left in stdin. So let’s work through our previous I/O operations and see what might involve putting a newline in stdin.

                    And we see scanf. How does scanf work? It takes input from the user. Then it attempts to parse the input into various tokens you specify. In your case, you want the user to type in a number. So let’s say I type in 4. Since I also hit the enter key, what we really have is 4\n. Now, scanf parses that input, and extracts 4. And it leaves everything else alone. So stdin now contains \n. And when you call fgets, it picks out the \n and returns immediately.

                    Wrong solution: fflush(stdin). Flushing is only defined for output streams. Not input.

                    Solution 1: Change your scanf to fgets, and manually convert it to an integer.
                    Solution 2:
                    [code=c]
                    int ch = 0;
                    while((ch = getc(stdin)) != EOF && ch != '\n');
                    [/code]
                    That is how you “flush” stdin.

                    Comment

                    • Barbosapt
                      New Member
                      • Jan 2008
                      • 6

                      #11
                      Originally posted by Savage
                      Both of these functions(gets and fgets) on error or EOF returns NULL.Have you checked to see whether this functions passes or not?

                      Also,I'm not suggesting that following is a good solution but it might work:

                      You said that next call to gets worked,so have you tried to put another call to gets(or fgets) after that one?
                      That worked thank you Savage.

                      oler1s thanks too...but im too lazy to do that :P

                      Comment

                      • sicarie
                        Recognized Expert Specialist
                        • Nov 2006
                        • 4677

                        #12
                        Originally posted by Barbosapt
                        oler1s thanks too...but im too lazy to do that :P
                        Goal in life to be featured in thedailywtf.com ?

                        Otherwise, I'd say put the effort in now. Then you'll learn it, and it won't take effort, you'll know to design it that way instead of changing it later (or finding other odd errors later).

                        Comment

                        • mikh
                          New Member
                          • Nov 2007
                          • 3

                          #13
                          Originally posted by oler1s
                          Your code confirms my suspicions. Let’s work backwards, to see how one might diagnose the problem. Remember that information about the various C functions can be found in documentation, easily googled. Problem: fgets seems to be skipped.

                          What does fgets do? It extracts from the file stream (in your case stdin) until it reaches a newline. Then it returns. So perhaps fgets isn’t being skipped, but is returning right away. Why would it do that? Perhaps because there is something already in stdin. Since it’s returning right away, it stands to reason there is a newline left in stdin. So let’s work through our previous I/O operations and see what might involve putting a newline in stdin.

                          And we see scanf. How does scanf work? It takes input from the user. Then it attempts to parse the input into various tokens you specify. In your case, you want the user to type in a number. So let’s say I type in 4. Since I also hit the enter key, what we really have is 4\n. Now, scanf parses that input, and extracts 4. And it leaves everything else alone. So stdin now contains \n. And when you call fgets, it picks out the \n and returns immediately.

                          Wrong solution: fflush(stdin). Flushing is only defined for output streams. Not input.

                          Solution 1: Change your scanf to fgets, and manually convert it to an integer.
                          Solution 2:
                          [code=c]
                          int ch = 0;
                          while((ch = getc(stdin)) != EOF && ch != '\n');
                          [/code]
                          That is how you “flush” stdin.

                          You are my hero! Now, why didn't I think about that earlier? Thank you soooooo much :-*

                          Comment

                          Working...