C programming - Scanf/gets unexpected behaviour - c

The program is supposed to do the following:
Add Major details
Add University details
Add major to university
Update major cost
Search for a major
Before completing the main function I'm facing a problem:
When I use scanf instead of gets in the functions, It asks 2 questions without letting me to fill the previous one. ex: Enter university's name: Enter university's address:
And when I used gets I faced the same problem.
If there's any other mistake please hint me
Thanks in advance!
#include <stdio.h>
#include <string.h>
//Define Structures
typedef struct {
char name[30];
char department[30];
int nb_students;
int credits;
float cost;
char adv_name[15];
}Major;
typedef struct {
char name[50];
char address[30];
Major uni_majors[50];
int nb_majors;
}University;
// Define Functions Prototypes
Major majors_function();
University university_function();
void AddMajor(Major *major,University *university);
University UpdateMajor(char nameMajor[], University U, float newCost);
void SearchMajor(Major major,University university);
int main(int argc, const char * argv[])
{
Major new_major;
University new_university;
new_major = majors_function();
new_university = university_function();
return 0;
}
// Fills The Major Details Function
Major majors_function() {
Major major;
printf("Enter Major name: ");
gets(major.name);
printf("Enter Department name: ");
gets(major.department);
printf("Enter number of students: ");
scanf("%d",&major.nb_students);
printf("Enter number of credits: ");
scanf("%d",&major.credits);
printf("Enter the cost of credit: ");
scanf("%f",&major.cost);
printf("Enter the Advisor's Last Name: ");
scanf("%s",major.adv_name);
return major;
}
// Fills the university details Function
University university_function() {
University university;
printf("Enter university's name: ");
gets(university.name);
printf("Enter university's address: ");
gets(university.address);
printf("Enter number of majors in this univeristy: ");
scanf("%d",&university.nb_majors);
return university;
}
// Adds Major to a university
void AddMajor(Major *major,University *university) {
university->nb_majors = 0;
if(university->nb_majors <50) {
university->uni_majors[university->nb_majors] = *major;
}
else
printf("No Available space");
university->nb_majors++;
}
// Update Major's Cost
University UpdateMajor(char nameMajor[], University U, float newCost) {
if(strcmp(nameMajor,U.uni_majors->name)) {
U.uni_majors->cost = newCost;
}
return U;
}
// Searches for a major in a university
void SearchMajor(Major major,University university) {
if(strcmp(university.uni_majors->name,major.name))
printf("The total cost of this major is %.2f",(major.cost*major.credits));
else
printf("There is no such major!");
}

When using scanf to scan strings or characters. you might want to skip leading whitespace (like newlines). This can simply be done by asking scanf to skip whitespace, by adding a single space in front of the format code, like
scanf(" %s",major.adv_name);
/* ^ */
/* | */
/* Note space */
You might want to read more about scanf and its siblings on e.g. this reference page.

NEVER NEVER NEVER NEVER NEVER NEVER NEVER NEVERN NEVER NEVER use gets, not for homework assignments, even for toy code. It was deprecated in the 1999 standard and has been removed from the 2011 standard. It will introduce a major point of failure in your program. Use fgets instead:
fgets( major.name, sizeof major.name, stdin );
and check the return value to make sure it succeeded.
Alternately, you can use scanf, but you'll want to specify the max buffer size in the conversion specifier:
scanf( "%29s", major.name ); // leave 1 space for the 0 terminator
The only problem with this is that the size has to be hardcoded; you can't pass it as an argument like you do with printf. Alternately, you can build the format string at runtime, like:
char fmt[5]; // good for %0s to %99s
sprintf( fmt, "%%%zus", sizeof major.name );
...
scanf( fmt, major.name );
Frankly, you're better off using fgets for everything, including the numeric inputs.
char inbuf[10];
char *chk;
// Read the number of students as text, then convert with the
// strtol library function; allows us to catch and reject
// non-numeric input.
printf( "Enter number of students: " );
fflush( stdout );
if ( fgets( inbuf, sizeof inbuf, stdin ) != EOF )
{
int tmp = (int) strtol( inbuf, &chk, 10 );
if ( isspace( *chk ) || *chk == 0 )
{
major.nb_students = tmp;
}
else
{
fprintf( stderr, "%s is not a valid number\n", inbuf );
}
}

Related

How do you ask the User multiple questions in C?

I am new to "C programming" and I have Googled for my answer, but I can't seem to get what I am looking for. I am making a simple 2 question program. The code is listed below:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char characterName[] = "Mike";
int age = 0;
printf("Enter your age, %s.\n", characterName);
scanf("%d", &age);
printf("Your being %d is old older than me and my brother "
"which was the first computer.Hahaaa.... \n", age);
return 0;
}
This is the next question:
char str[50];
{
printf("Anything to say about my comment? \n");
scanf ("%[^\n]", str);
printf("That was a good answer. I wasn't expecting that from you.\n");
return 0;
}
How about a function to ask a question, and return a response?
#include <stdio.h>
/*
* Prompt the user with the given question, return their
* input in answer, up to max_answer_length bytes
* returns 1 for ok, 0 on error.
*/
int askQuestion(const char *question, char *answer, const size_t max_answer_length)
{
int input_ok = 1;
// Show the user the question
printf( "%s: ", question );
// Throw away any existing input in the user's input-queue
// (like if they answered with a really-long string previously)
fflush(stdin);
// Read a line of input from the user into <answer>, but not more
// than <max_answer_length>-1 bytes are accepted (see fgets() for details)
// If the fgets() returns EOF or an error, make sure we remember it
if ( fgets( answer, max_answer_length, stdin ) == NULL )
input_ok = 0;
// return whether there was an error on input
return input_ok;
}
int main(void)
{
char answer_buffer[200];
askQuestion( "What is your favourite fruit?", answer_buffer, sizeof(answer_buffer) );
printf( ">> %s\n", answer_buffer );
askQuestion( "How long have you been programming C?", answer_buffer, sizeof(answer_buffer) );
printf( ">> %s\n", answer_buffer );
return 0;
}

Storing user input whilst still asking questions

Firstly, i know the source code below is long and you're not really supposed to post code like this, but i really don't understand why it's not working or how i could explain my issue without posting it like this.
Im trying to store the answer to each of the questions asked in it and display them at the end of the script. The biggest problem im having is that i get the error
"subscripted value is neither array nor pointer nor vector scanf("%s", a[i].incdest);"
The program doesn't accept a[i].incdest. it does this for all of the array values.
it is also saying that in function main variable "comp1" is undeclared.
#include<stdio.h>
#include<string.h>
int c_s(char*, char*);
typedef struct
{
char constab[30];
char vicwit[15];
char witdet[200];
char incdest[300];
char comp1[15];
char comp2[200];;
} sheetstore;
#define ARRAYLEN 2
sheetstore a[ARRAYLEN];
FILE *fp;
int main()
{
int i, a;
char wit[10] = "witness";
char yes[10] = "yes";
char comp1[10];
fp = fopen("sheetstore.dat","a+");
printf("Hate crime reporting system\n\n\n");
printf("If the crime you are reporting is an emergency,\nplease call 999, do not proceed any further with this form\n\n\n\nPlease press enter to confirm you have read the above and continue\n");
char enter = 0;
while (enter != '\r' && enter != '\n') { enter = getchar(); }
for( i=0; i<ARRAYLEN ; i++)
{
printf("Which police constabulary did the offence take place in?\n\n");
scanf("%s", a[i].constab);
printf("Are you a victim or witness of the crime?\nPlease answer victim/witness\n\n");
scanf("%s", a[i].comp1);
int res1 = (strcmp (comp1, wit));
if(res1 == 0){
printf("Please enter the details including phone number and address of any other witnesses that were present\n");
}
scanf("%s", a[i].witdet);
else{
printf("Where did the incident take place?\nIf in a house please provide the full address including postcode\n");
scanf("%s", a[i].incdest);
}
fwrite(&a[i], sizeof(a), 1, fp);
}
fclose(fp);
fopen("sheetstore.dat", "r");
for(i=0; i<ARRAYLEN; i++)
{
fread(&a[i], sizeof(a), 1, fp );
printf("Which police constabulary did the offence take place in? : %s\n", a[i].constab);
printf("Are you a victim or witness of the crime? : %s\n", a[i].comp1);
printf("Please enter the details including phone number and address of any other witnesses that were present : %s\n", a[i].witdet);
printf("Where did the incident take place? : %s\n", a[i].incdest);
}
fclose(fp);
return 0;
}
the main issue that i saw in your code, is that you shadowed the array a (sheetstore a[ARRAYLEN];) by declaring an int with the same name in your main().
you also had a scanf stament mislocated.
i fixed your code and put in a comment for every change - now, i don't persume to check the functionality of your code but at least this will compile and hopefully will give you a better understanding where you were wrong - from here it is up to you:
#include<stdio.h>
#include<string.h>
int c_s(char*, char*);
typedef struct
{
char constab[30];
char vicwit[15];
char witdet[200];
char incdest[300];
char comp1[15];
char comp2[200];;
} sheetstore;
#define ARRAYLEN 2
sheetstore sheetArr[ARRAYLEN]; //change this 'a' to avoid shadowing by the decleration on 'int a' in main
FILE *fp;
int main()
{
int i, a;
char wit[10] = "witness";
char yes[10] = "yes";
char comp1[10];
fp = fopen("sheetstore.dat","a+");
printf("Hate crime reporting system\n\n\n");
printf("If the crime you are reporting is an emergency,\nplease call 999, do not proceed any further with this form\n\n\n\nPlease press enter to confirm you have read the above and continue\n");
char enter = 0;
while (enter != '\r' && enter != '\n') { enter = getchar(); }
for( i=0; i<ARRAYLEN ; i++)
{
printf("Which police constabulary did the offence take place in?\n\n");
scanf("%s", sheetArr[i].constab);//change name from 'a'
printf("Are you a victim or witness of the crime?\nPlease answer victim/witness\n\n");
scanf("%s", sheetArr[i].comp1);//change name from 'a'
int res1 = (strcmp (sheetArr[i].comp1, wit));//compare with the value set in the struct
if(res1 == 0){
printf("Please enter the details including phone number and address of any other witnesses that were present\n");
/*this scanf should be inside the brackets of 'if(res1 == 0)' */
scanf("%s", sheetArr[i].witdet);//change name from 'a'
}
else{
printf("Where did the incident take place?\nIf in a house please provide the full address including postcode\n");
scanf("%s", sheetArr[i].incdest);//change name from 'a'
}
fwrite(&sheetArr[i], sizeof(sheetstore), 1, fp);//write a single struct
}
fclose(fp);
fopen("sheetstore.dat", "r");
for(i=0; i<ARRAYLEN; i++)
{
fread(&sheetArr[i], sizeof(sheetstore), 1, fp );//read a single struct
printf("Which police constabulary did the offence take place in? : %s\n", sheetArr[i].constab);
printf("Are you a victim or witness of the crime? : %s\n", sheetArr[i].comp1);
printf("Please enter the details including phone number and address of any other witnesses that were present : %s\n", sheetArr[i].witdet);
printf("Where did the incident take place? : %s\n", sheetArr[i].incdest);
}
fclose(fp);
return 0;
}
In addition to some useful comments posted above (meaningful variable names, line width not to be too long for readability), in general sense, your problem is due to two thing: in the body of the main function you declare an int a which is used instead of your global array a[ARRAYLEN]. Hence, you cannot refence a[i].incdet etc. Just comment or remove the int a from the main function. Secondly, your scanf("%s", a[i].witdet); should be in the body of the if statement above according to the program logic. I you do these two changes, the code will compile. However if you pass -Wall -Werror to the compiler, it will yields an error like error: unused variable ‘yes’ [-Werror=unused-variable]
char yes[10] = "yes";. Just comment this line to avoid using uncessary memory space on the stack.
The following proposed code:
corrects the first 50+ lines of your code.
Please correct your posted code so it cleanly compiles
for flexibility, separates the definition of the struct from the typedef of the struct
properly checks for error indications from system functions
honors the right margin (usually 72 or 80 characters)
replaces the CPU cycle intensive calls to printf() with calls to puts() when appropriate
This is only a guide for the first 50 lines of the OPs code. It is not a complete code replacement.
and now the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// prototypes
int c_s(char*, char*);
struct sSheet
{
char constab[30];
char vicwit[15];
char witdet[200];
char incdest[300];
char comp1[15];
char comp2[200];
};
typedef struct sSheet sheetstore;
#define ARRAYLEN 2
sheetstore a[ARRAYLEN];
FILE *fp;
int main( void )
{
int i;
char wit[10] = "witness";
//char yes[10] = "yes";
char comp1[10];
fp = fopen("sheetstore.dat","a+");
if( !fp )
{
perror( "fopen for appending to 'sheetstore.dat' failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
puts("Hate crime reporting system\n\n\n");
puts("If the crime you are reporting is an emergency,\n"
"please call 999, "
" do not proceed any further with this form\n\n\n\n"
"Please press enter"
" to confirm you have read the above and continue\n");
int enter = 0;
while (enter != '\r' && enter != '\n')
{
enter = getchar();
}
for( i=0; i<ARRAYLEN ; i++)
{
puts("Which police constabulary did the offence take place in?\n\n");
if( scanf("%29s", a[i].constab) != 1)
{
fprintf( stderr, "scanf for which police constabulary failed" );
fclose( fp ); // cleanup
exit( EXIT_FAILURE );
}
// implied else, scanf successful

Scan a white space/whole line in c

So, I know this question has been asked before, but I can't seem to make anything work. What I have right now is this:
#include<stdio.h>
struct ClothingCustomer{
char name[20];
int age;
double inseam;
};
struct ClothingCustomer createACustomer(){
struct ClothingCustomer aCustomer;
printf("Enter Customer Name: ");
scanf("%s",aCustomer.name);
printf("Age: ");
scanf("%d",&aCustomer.age);
printf("Inseam: ");
scanf("%lf",&aCustomer.inseam);
return aCustomer;
};
int main(){
FILE* customersFile = fopen("customers.txt","w");
for (int i = 0; i < 5; i++){
struct ClothingCustomer aCustomer = createACustomer();
fprintf(customersFile, "%s %d %lf\n", aCustomer.name, aCustomer.age, aCustomer.inseam);
}
fclose(customersFile);
return 0;
}
No matter what I do to try to make it scan more than one word, like a first/last name or something, it works, but here's what I get in the console while running this(with the scan options to try to get past a white space listed below; the above code functions correctly, but doesn't allow white space):
Enter Customer Name:
Age:
Inseam:
Enter Customer Name: Age:
Inseam: Enter Customer Name: Age:
Inseam:
Enter Customer Name: Age:
Inseam:
Enter Customer Name: Age:
Inseam:
How can I make it not do this? I've tried using:
[^\n]
fgets(name, sizeof(name), stdin);
and the same thing happens every time.
This Will Work
#include<stdio.h>
#include<string.h>
struct ClothingCustomer createACustomer(void);
struct ClothingCustomer{
char name[20];
int age;
double inseam;
};
struct ClothingCustomer createACustomer(void){
struct ClothingCustomer aCustomer;
{ //From Here Starts The Part in Which You Are Having Problems.
char c;
int i;
printf("Enter Customer Name: ");
scanf("%s",aCustomer.name);
i = strlen(aCustomer.name); // length of user input till first space
do{
scanf("%c", &c);
aCustomer.name[i++] = c; // reading characters after first space (including it)
}while (c != '\n'); // until user hits Enter
aCustomer.name[i - 1] = 0; // string terminating
}
printf("Age: ");
scanf("%d",&aCustomer.age);
printf("Inseam: ");
scanf("%lf",&aCustomer.inseam);
return aCustomer;
};
int main(){
FILE* customersFile = fopen("customers.txt","w");
int i = 0;
for (i = 0; i < 5; i++){
struct ClothingCustomer aCustomer = createACustomer();
fprintf(customersFile, "%s %d %lf\n", aCustomer.name, aCustomer.age,aCustomer.inseam);
}
fclose(customersFile);
return 0;
}
I Highly Recommend You To Take A Look on this answer , it will help you a lot , the method I used in here is mentioned in the above answer.Please Give That answer Credit If this method works for you.
Here is the explanation for the part which you were having problem in , how is it working now.
How this works? When user inputs characters from standard input, they will be stored in string variable until first blank space. After that, rest of entry will remain in input stream, and wait for next scanf. Next, we have a for loop that takes char by char from input stream (till \n) and appends them to end of string variable, thus forming a complete string same as user input from keyboard.
Unclear why scanf(" %19[^\n], aCustomer.name) failed for OP.
Rather than use scanf() for complex input, separate user input from parsing.
Drop use of scanf() completely and use fgets() to fetch user input. Use sscanf(), strtod(), strtol(), strtok() etc. for parsing.
Be sure to check the result of user input and success of parsing functions.
OP has not indicated how to handle troublesome input. The below returns a zero-ed ClothingCustomer in that case. Additional error codes or error messages may be useful.
struct ClothingCustomer createACustomer(void) {
// Suggest initializing
struct ClothingCustomer zero = { 0 };
struct ClothingCustomer aCustomer = { 0 };
char buffer[100];
printf("Enter Customer Name: ");
fflush(stdout); // insure prompt is seen before asking for input
if (fgets(buffer, sizeof buffer, stdin) == NULL) return zero;
buffer[strcspn(buffer, "\r\n")] = '\0'; // lop off potential line ending
if (strlen(buffer) >= sizeof aCustomer.name) return zero; // too long
strcpy(aCustomer.name, buffer);
printf("Age: ");
fflush(stdout);
if (fgets(buffer, sizeof buffer, stdin) == NULL) return zero;
if (sscanf(buffer, "%d", &aCustomer.age) != 1) return zero;
// Let us do some range checking
// https://en.wikipedia.org/wiki/List_of_the_verified_oldest_people
if (aCustomer.age < 0 || aCustomer.age > 122) return zero;
printf("Inseam: ");
fflush(stdout);
if (fgets(buffer, sizeof buffer, stdin) == NULL) return zero;
if (sscanf(buffer, "%lf", &aCustomer.inseam) != 1) return zero;
return aCustomer;
}

s expects argument of type char c but argument 2 has type 'int' warning and bad return

Yes ,I know that this question was already asked for many times ,but none of these helped me to discover the problem (duplicate...yeah). I want to read from input a series of strings into an array and then search from 'First Name'. If the name exist ,I want to display all the data stored in that element of array (I attached the code to undestand easily). When I run it ,I read from keyboard all the data ,but it returns me absolutely nothing.
#include<stdio.h>
typedef struct record {
char name[10],lname[10],phone[10],bday[10];
};
void main() {
struct record rec;
char search;
int i,nr;
printf("\nInput number of records: ");
scanf("%d",&nr);
for (i=0 ; i<nr ;i++) {
printf("First name: ");
scanf("%s",&rec.name[i]);
printf("Last name: ");
scanf("%s",&rec.lname[i]);
printf("Phone: ");
scanf("%s",&rec.phone[i]);
printf("Bday: ");
scanf("%s",&rec.bday[i]);
}
printf("Input the first name for searching: ");
scanf("%s",&search);
for (i=0 ;i<nr;i++) {
if (search == rec.name[i]) {
printf("First name: %s\nLast name: %s\nPhone: %s\nB-day: %s",rec.name[i],rec.lname[i],rec.phone[i],rec.bday[i]);
}
}
}
NOTE: I already replaced
scanf("%s",&rec.name[i]);
with
scanf("%s",rec.name[i]);
but no effect.
I believe there are a lot of problems with your code.
Firstly in this line:
scanf("%s",&search);
You have declared search as only a char, when really you want an array of chars. You also don't need & with search, as an array decays to a pointer to the first element.
It instead should be like this:
char search[10];
scanf("%9s", search); /* %9s to avoid buffer overflow */
You need to make this change to all your other scanf() calls, as this seems to be everywhere in this code.
It also seems that you want to create an array of records(structures), So you might need to make this after getting the value of nr. You can create it like this:
struct record rec[nr]; /* array of nr structures */
This also means calls like this:
rec.name[i]
Don't make sense, as you are iterating over the characters within a name, not over all the records in struct records.
This needs to be instead:
rec[i].name
Secondly, Your using == to compare strings, when you should be using strcmp instead. Using == will only compare the base address of the strings, not the actual contents of strings.
Your line should be this instead:
if (strcmp(search, rec[i].name) == 0) {
If you read the manual page for strcmp(), checking for a return value of 0 means that both strings are equal in comparison.
Lastly, in your first scanf() call:
scanf("%d",&nr);
You should really check the return value of this:
if (scanf("%d", &nr) != 1) {
/* exit program */
}
Note: For reading strings, you should really be using fgets instead. You can try upgrading to this later, but I think it is better to understand these basics first.
Here is working example of what your program should do:
#include <stdio.h>
#include <string.h>
#define STRSIZE 10
typedef struct {
char name[STRSIZE+1]; /* +1 to account for null-btye at the end */
char lname[STRSIZE+1];
char phone[STRSIZE+1];
char bday[STRSIZE+1];
} record;
int main() {
char search[STRSIZE+1];
int i,nr;
printf("\nInput number of records: ");
if (scanf("%d", &nr) != 1) {
printf("Invalid input.\n");
return 1;
}
record rec[nr]; /* array of records */
for (i = 0; i < nr ; i++) {
printf("First name: ");
scanf("%10s", rec[i].name);
printf("Last name: ");
scanf("%10s", rec[i].lname);
printf("Phone: ");
scanf("%10s", rec[i].phone);
printf("Bday: ");
scanf("%10s", rec[i].bday);
}
printf("Input the first name for searching: ");
scanf("%10s", search);
for (i = 0; i < nr; i++) {
if (strcmp(search, rec[i].name) == 0) {
printf("First name: %s\nLast name: %s\nPhone: %s\nB-day: %s\n",rec[i].name,rec[i].lname,rec[i].phone,rec[i].bday);
} else {
printf("Record not found.\n");
}
}
return 0;
}
The numeric input leaves a new line character in the input buffer, which is then picked up by the character input. when numeric input with scanf() skips leading white space, character input does not skip this leading white space.
Use a space before %c and it will help you cause if space is not used then a buffer added with value .so that use space before %c
scanf(" %c",&rec.name[i]);

Using strcmp in an if statement

I am fairly new to C, and I am trying to understand using strings and strcmp to compare two strings in an if statement.
My goal is to be able to run a different function depending on what the user has inputted.
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
void gasbill();
void electricitybill();
int main()
{
char input[20];
const char gasCheck[4] = "gas";
const char electricityCheck[13] = "electricity";
printf("Your bills explained!\n\n");
printf("In this application I will go through your gas and electricty bills.\n");
printf("I will explain how each of the billing payments work, \nand the calculations that go on,\n");
printf("to create your bill.\n\n");
printf("Please choose a bill to get started with:\n- gas\n- electricity\n\n");
fgets(input, 20, stdin);
if (strcmp (input, gasCheck)== 0){
printf("\nPreparing to run Gas bill!\n\n");
system("PAUSE");
system("cls");
gasbill();
system("PAUSE");
}
else if (strcmp (input, electricityCheck)== 0){
printf("\nPreparing to run Electricity bill!\n\n");
system("cls");
electricitybill();
system("PAUSE");}
else {
printf("\nError exiting...\n\n");
system("PAUSE");
}
return 0;
}
void gasbill()
{
float balanceBroughtForward, gasThisQuarter, subTotalPerQuarter;
char poundSign = 156;
printf("******Your gas bill, explained!******\n\n\n");
printf("Hello, and welcome to your gas bill, explained. Let's get started.\n");
printf("Please enter the balance brought forward from your previous statement: \n\n%c", poundSign);
scanf("%f", &balanceBroughtForward);
printf("\nHow this works:\n- The money that you did not pay last quarter for your gas bill\nhas been added to this quarterly payment\n\n");
printf("\nNext let's add this to the amount of gas you have spent this quarter. \n(how much gas have you used so far in this billing period?)");
printf(": %c", poundSign);
scanf("%f", &gasThisQuarter);
printf("\n\nNow what? The two values that you have entered\n(balance brought forward
and gas spent this quarter)\nare added together, %c%3.2f + %c%3.2f\n", poundSign,
balanceBroughtForward, poundSign, gasThisQuarter);
subTotalPerQuarter = (balanceBroughtForward + gasThisQuarter);
printf("This is");
}
void electricitybill()
{
printf("Empty");
system("PAUSE");
}
When ever it runs the if statement it always executes the gasBill function and not the electricityBill function.
Thanks in advance.
fgets will return a string which ends with a newline (\n). From its documentation
Reads characters from stream and stores them as a C string into str
until (num-1) characters have been read or either a newline or the
end-of-file is reached, whichever happens first.
You could either test for a trailing newline and strip it off
fgets(input, 20, stdin);
size_t len = strlen(input);
if (input[len-1] == '\n') {
input[len-1] = '\0';
}
or read user input using scanf instead.
scanf("%19s", input);
As an aside
const char gasCheck[4] = "gas";
const char electricityCheck[13] = "electricity";
could be declared slightly more easily and safely as
const char *gasCheck = "gas";
const char *electricityCheck = "electricity";
(This form saves copying the string literals into stack variables. More importantly, it removes a potential source of bugs if you hard-code too small a length for the arrays.)
fgets() read characters from stdin until a newline is seen or an EOF, if newline was seen, it would be stored in the array.Anyway, fgets() appends a null character to the array.
so if you want end your input by newline, my minor alteration is here, change this
const char gasCheck[4] = "gas";
const char electricityCheck[13] = "electricity";
to
const char gasCheck[5] = "gas\n";
const char electricityCheck[14] = "electricity\n";

Resources