Solved

fgets is not working, IGNORES: fgets(textArray, BUFSIZ, stdin);

Posted on 2004-09-26
10
661 Views
Last Modified: 2012-08-13
My code is below, and everything works fine.  I need this solve ASAP please.  he first fgets() function isn't working.  As if the compiler is ignoring it.

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

int main(void) {

      //VARIABLE DECLARATION
      FILE *ifp;
      char *array;
      char fileName[10];
    char textArray[BUFSIZ*10];
    char cryptArray[BUFSIZ*10];
    char rawKey[BUFSIZ*10];
    int shift, cryptShift, choice;      
      int i=0, cnt1 = 0, arraySize=0;
      char val;
      

      printf("\nWhat would you like to encrypt?  1. Screen Input\n");
      printf("                                 2. Read from file\n\n");
      scanf("%d", &choice);
      printf("%d", choice);

      switch(choice)
      {
            case 1:
                  goto userInput;
            case 2:
                  goto fileInput;
      }


fileInput:
      printf ("Enter a file to read from : ");
      gets (fileName);
      printf ("\nFile to open: %s\n",fileName);

      ifp = fopen(fileName, "r");

      /*if(ifp == NULL)
            printf("not found");
      else
            printf("file found");*/

      for(cnt1=0; cnt1<100;cnt1++)
      {
            val = getc(ifp);
            //fscanf(ifp, "%c", &val);
            array = &val;
            printf("%d\n", array[cnt1]);
      }

/*
      for(cnt1=0; cnt1<arraySize; cnt1++)
      {
            fscanf(ifp, "%lf", &val);
            array[cnt1] = val;
            //printf("\t\tarray[%d]: %.8lf\n", cnt1, array[cnt1]);
      }
*/


userInput:
    printf("\n\nEnter text to encrypt: ");
    //get into, save to textArray, max size of BUFSIZ, from keyboard
      
            fgets(textArray, BUFSIZ, stdin);
      if (textArray==NULL)
      //clears the buffer
    fflush(stdin);

//////////////////////////////////////
      ////////////////////////////////////////
      
//goto userInput;
      printf("Enter raw key): ");
        fgets(rawKey, BUFSIZ, stdin);
        fflush(stdin);
 

    for (;;){
        //converts the string into ascii
            shift = atoi(rawKey);
        //encrypts the ascii
            cryptShift = ((shift) % 26);

            if (shift == NULL)
            {
            printf("No data recieved!\n");
                  break;
            }
        else
            break;
    }
   
    while (textArray[i]){
        cryptArray[i] = textArray[i] + cryptShift;
        i++;
    }
    cryptArray[i] = '\0';

    printf("\nPlain Text:\n%s", textArray);
    printf("\nEncryted Text:\n%s\n\n", cryptArray);  
    return 0;
}
0
Comment
Question by:bahsousj
  • 2
  • 2
  • 2
  • +3
10 Comments
 
LVL 1

Assisted Solution

by:rghome
rghome earned 20 total points
ID: 12154667
bahsousj,

There are lots of bugs in this code!! You need to spend some time on it.

First, you should not use goto. Ever. Except maybe to jump to some error handing at the end of function in the case of an error. In your program, in the case the the user selects "2" both fileInput AND userInput will be run. You should change your program to have two different functions: one for user and one for file input.

Second,

     for(cnt1=0; cnt1<100;cnt1++)
     {
          val = getc(ifp);
          //fscanf(ifp, "%c", &val);
          array = &val;
          printf("%d\n", array[cnt1]);
     }

This is wrong. Val is a single character, so you can't make array point at it, and then access an index of array. There is only one character! I am not sure what you are trying to do, but just typing printf("%d\n", getc(ifp)) would do the same thing. If you want to store the characters in an array, then declare an array (not a char*) and use array[cnt1] = getc(ifp);

Third,

You test if (textArray==NULL) // is wrong. textArray can never be NULL because you have declare it as an array.

Fourth,

for (;;){
        //converts the string into ascii
          shift = atoi(rawKey);
          ...
         if (shift == NULL)

shift should not be compared with NULL. shift is an integer and atoi does not return NULL on failure. And anyway, why is this a loop ? You always break everytime, so why create a loop ?

There are more problems, but I am short of time; I hope that helps, but you are really going to have to go through this program more carefully and sort it out and then if you have some problems, post some more specific questions. I could write the program for you, but if you are learning 'C' (I guess that you are) it wouldn't really help you.

0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12154710
Many comments:
- You can use gets(textArray) as an alternative
- I don't see your BUFSIZ declaration, maybe it is wrong
- The if(textArray==NULL) is wrong, it couldn't be never NULL.
- If you want to check if textArray is **empty** use: if (!*textArray)
- Try to use puts(textArray) to check contents.
0
 
LVL 45

Expert Comment

by:Kdo
ID: 12155273

Hi bahsousj,

Both of the previous posters are correct in that this code needs some "streamlining", but that's part of the learning process.

Here's the loop from your program that does the encryption, the "real" problem lies here, so let's disect this:

1>>    for (;;){
        //converts the string into ascii
2>>          shift = atoi(rawKey);
        //encrypts the ascii
3>>          cryptShift = ((shift) % 26);

4>>           if (shift == NULL)
          {
            printf("No data recieved!\n");
               break;
          }
        else
            break;
    }

1>>  Legal, but while(1) is more commonly used.  :)

2>>  The probable culprit.  If the string starts with any character other than a digit, atoi() will return a zero.

3>>  0 % 26 == 0

4>>  The zero returned by atoi() is being examined.  This will always be zero unless the first character in the string is a digit.


Good Luck,
Kent
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 12155425
BUFSIZ is a contant defined in stdio.h

Why your fgets statement is not executing is because scanf("%d",&choice); leaves the \n in the buffer and fgets read in that trailing \n as the first input and is terminated by seeing that \n.

fflush(stdin);
before the fgets statement will work for you,but I should warn you that fflush() is defined only for output streams and should not be used for input streams as it invokes undefined behaviour.

You could use something like:
while(getchar()!='\n');

to clean the stdin buffer of that trailing \n.


0
 

Author Comment

by:bahsousj
ID: 12155855
thanks for all your suggestions...kDo is tho, this is Caesar encryption..  It is supposed to accept iput from a file, or the keyboard.  I convert it to integers, encrypt and convert back to text and save to another file.

I used the goto spagetti code temporarily, until i got everything else working.

In the meantime, i will try your suggests in about 6 hours, and post the results.Thanks for the help.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Expert Comment

by:rghome
ID: 12156034
OK,

If you are accepting input from file and keyboard, the trick is to just use the same code, but change the FILE handle only.

Create a function to do the encrption, e.g.,

void encrption(FILE *fp) { ...

In the case of a file, simply use fopen to open the file and pass the resulting file handle to it. In the case of keyboard, you can use stdin without opening it and pass stdin to the function.

Saves you a lot of typing, and it is also better because the encrytption function only has to worry about the algorithm, and not about which file it is talking to.
0
 
LVL 23

Expert Comment

by:Mysidia
ID: 12156659
The problem is that you do a      scanf("%d", &choice);
before the fgets.

scanf won't eat the end-of-line, it will leave the \n in input, hence
the following gets will just read what it left

perhaps try
     scanf("%d\n", &choice);

or use fgets() to get the choice also

char tempbuf[256];
...
...
  fgets(tempbuf, sizeof tempbuf, stdin);
  choice = atoi(tempbuf);
0
 

Author Comment

by:bahsousj
ID: 12167627
I appreciate all you inputs.  I used a little from everyone.  

Mysidia actually resolved the original problem of fgets() not being recognized, however, thats an extra array I need to declare and more code... there must be an easier way.. C-programming cannot possible be that silly!

Nonetheless, it did work but how can one assume to use fgets and an array instead of a simple scanf()... there must be another way..     what is it????   getchar() doesnt work  getc()???

I havent touched C-programming in a while, and rghome is right, there were lots of little bugs in my code.  I utilized some functions to make my code more readable and re-usable.  I eliminated the silly goto-statements, however there is a problem.
 
I'd like to have the following inside my encrypt function, however, its erroneous  Maybe its the way I added the parameters, or passed the values back and forth:  Any suggestions??

                             while (textArray[i]){
            cryptArray[i] = (textArray[i] + cryptShift);
            i++;
                         }      
My code is below and I think its much better than before... it took me a few hours to code, longer than usual.  
Lastly, im having trouble saving the file into an array, textArray[].  After saving to textArray, i will encrypt the input
===========================================================
#include <stdio.h>
#include <stdlib.h>

int encrypt(int cryptShift);
char keyboardInput(char textArray[]);
char fileInput(char textArray[]);

int main(void) {

      char textArray[BUFSIZ];
      char cryptArray[BUFSIZ];
      int cryptShift=0, i=0, choice=0;
      char tempbuf[BUFSIZ];

error:
      printf("What would you like to encrypt?  1.  Keyboard Input\n");
      printf("                                 2.  File Input  \n\n");
      
      ////  There must be another way!!!!!
      fgets(tempbuf, sizeof tempbuf, stdin);
      choice = atoi(tempbuf);

      switch(choice){
            case 1:
                  keyboardInput(textArray);  /*Function call*/
                  break;
            case 2:
                  fileInput(textArray);      /*Function call*/
                  break;
            default:
                  printf("\nERROR, please make a correct selection\n\n");
                  goto error;                /*my only goto-statement*/
      }
      
      cryptShift = encrypt(cryptShift);  /*Function call*/
      
      while (textArray[i]){ /*The actual encryption is done in this block*/
            cryptArray[i] = (textArray[i] + cryptShift);
            i++;
      }
      cryptArray[i]='\0';

      /*Display the output, i'd like to eventually have this save to a new file rather than display to the screen*/
      printf("\nOriginal message : %s", textArray);
      printf("Encrypted message: %s\n\n", cryptArray);

      return 0;
}

char keyboardInput(char textArray[])
{
      printf("\t\tTAKING INPUT FROM THE KEYBOARD\n\n");
      printf("Enter text to encrypt: ");
      fgets(textArray, BUFSIZ, stdin);
      fflush(stdin);

      return *textArray;
}

char fileInput(char textArray[])
{
      char fileName[20];
      FILE *file;

      printf("\t\tTAKING INPUT FROM A FILE\n\n");
      printf("Enter a file to read from: ");
      gets(fileName);
      printf("\nFile to be read: %s", fileName);

      file = fopen(fileName, "r");

/*///////////////////////////////////////////////////////
      while(file != NULL)
      {
            if(textArray!=EOF)
            {
                  textArray = fgetc(file);
                  printf("%c", textArray);
            }
            else
               break;
      }
*//////////////////////////////////////////////////////
      if(file==NULL)
      {
            printf("Error: can't open file.\n");
            return 1;
      }
      else
      {
            printf("\n\n\t -File opened successfully- \n\n");

            while (file!= '\0')
            {
                  textArray = fgetc(file);
                  printf("%c", textArray);
                  cnt1++;
            }
      }
      fclose(file);
      return *textArray;
}



int encrypt(int cryptShift) /*This function takes the modulos of the input to encrypt*/
{
      int shift=0;

      printf("Enter raw key: ");
      scanf("%d", &shift);
      
      cryptShift = ((shift)%26);
      
      printf("\nshift: %d cryptShift: %d\n\n", shift, cryptShift);

      return cryptShift;
}


THANK YOU KINDLY, JONY
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 80 total points
ID: 12167924
Hi,

Did you read my comment before?

>>
Why your fgets statement is not executing is because scanf("%d",&choice); leaves the \n in the buffer and fgets read in that trailing \n as the first input and is terminated by seeing that \n.

fflush(stdin);
before the fgets statement will work for you,but I should warn you that fflush() is defined only for output streams and should not be used for input streams as it invokes undefined behaviour.

You could use something like:
while(getchar()!='\n');

to clean the stdin buffer of that trailing \n.
<<

0
 
LVL 45

Accepted Solution

by:
Kdo earned 400 total points
ID: 12168532


There is an easier way.  :)   Most of your setup controls can be reduced a lot.  The following snippet sets up variable 'input' as the stream to read for the data so that you can read keyboard or file input from the same function call.

FILE *input = NULL;   // Declare a stream pointer for input from any source

....

main ()
{
  char FileName[128];

  while (!input)
  {
     printf("What would you like to encrypt?  1.  Keyboard Input\n");
     printf("                                 2.  File Input  \n\n");
     
     switch(getchar ())
     {
          case '1':
               input = stdin;
               break;
          case 2:
               printf (" Enter the file name:  ");
               fgets (FileName, 128, stdin);
               input = fopen (FileName, "r");         // Need some sanity checks on this working correctly.
               break;
          default:
               printf("\nERROR, please make a correct selection\n\n");
               goto error;                /*my only goto-statement*/
     }
  }
}


Good Luck,
Kent
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now