I'm trying to ensure that the user has definitely entered an integer. However no matter what I type in, it doesn't seem to work.
Sometimes the scanf is completely ignored and the loop just prints out everything loads of times.
When I checked what the input was that the code took in, it was wrong as well.
Any ideas or help would be appreciated!
while (square_size == -1) {
square_size = get_input_size();
}
int get_input_size(void) {
int size;
printf("What size word square would you like to create? ");
scanf("%d", &size);
if (isdigit(size)) {
printf("VALID %d\n", size);
return size;
}
printf("ERROR: invalid input\n");
return -1;
}
Related
I am totally new to C.
I want to re-prompt when the input value is not a number and when it's a number it should be less than 1. when I give any sort of string it works correctly. But when I give any number it goes to the next line without printing "Number: ".Then in the next line, it prints "Number: "again if the input value is less than 1.
int x;
printf("Number: ");
while (scanf("%d", &x) != 1 || x < 1 )
{
printf("Number: ");
scanf("%*s");
}
and the result it gives me is this
result
It would be wise to use fgets to read the line, then use sscanf to parse the input. That way, you can get the line, then check if sscanf succeeds!
Simple example:
int target_number; // The number you will have at the end of this.
while (1) { // Loop for rechecking number
char line[16]; // See notes on how to read the whole line.
fgets(line, sizeof(line), stdin);
// We use 1 here because sscanf returns the number of format specifiers that are matched. Since you only need one number, we use 1.
if (sscanf(line, "%d", &target_number) != 1) {
fprintf(stderr, "Invalid Input! Please enter in a valid number.");
continue;
}
}
// Do whatever you will with target_number
Notes
You can see how to read the whole line here.
This code is not safe!
It does not protect against buffer overflow attacks and the like. Please see this on the right way to do this. If this is just for learning, you don't need to worry.
/*This is how it will work the way you want.
If I understand your goal correctly, of course?
If your goal was different,
please specify and I will try to solve it.*/
#include<stdio.h>
int main(void)
{
int x;
printf("Number: ");
while (scanf("%d.%*d", &x)!=1 || x<0)
{
if(x<0)
{
printf("Number: ");
continue;
}
else
printf("Number: ");
scanf("%*s");
}
printf("Hello world!");
return 0;
}
I am making a program that saves information about vehicles in an array made of structs and then prints it to a file. Included in the program are options to add and delete vehicles as well as printing out the saved vehicles and deleting vehicles. When choosing a vehicle to delete or print out I have to make sure the input from the user is an integer to prevent it from crashing, and if it is not an integer to give a custom error message and give the user another chance at the input. I have tried a couple of different approaches and the latest seemed promising but when running these functions I get "Segmentation fault: 11" regardless of if I input an integer or a character.
The functions seem to work just fine without the lines of code that are supposed to prevent crashing. Could someone please tell me what is causing the error or possible fixes to the problem. Thanks!
These are the functions that are causing the problem:
Function to remove vehicle:
This function takes in the array of structs as well as the int counter which counts the number of occupied spots in the array. The function then takes input from the user in the form of an int to choose which position to delete. The position can't be greater than counter or smaller than 0.
//Ta bort ett fordon
void del(int counter, fordon_t reg[])
{
int pos;
int i;
do{
printf("Vilken position ska tas bort?:");
char *tmp;
scanf("%s", tmp);
pos = atoi(tmp);
if (pos == 0)
{
printf("Var god och skriv en siffra\n");
}
}
while(pos == 0);
if(pos<0 || pos>=counter)
{
printf("Ogiltig position\n");
}
else
{
for(i=pos+1; i<counter; i++)
{
reg[i-1]=reg[i];
}
counter--;
for(i=0; i<counter; i++)
{
printf("%s %d %s %s %s\n", reg[i].owner.name, reg[i].owner.age, reg[i].type, reg[i].brand, reg[i].regnum);
}
}
}
Function to print out chosen vehicle:
This function works in the same way as the previous function but instead of deleting the chosen position it prints out the information on that position.
//Skriv ut specifikt fordon
void print_out(int counter, fordon_t reg[])
{
int val;
do
{
char *tmp;
printf("Vilken postition vill du se?:");
scanf("%s", tmp);
val = atoi(tmp);
if (val == 0)
{
printf("Var god och skriv en siffra\n");
}
}
while(val == 0);
if(val<0 || val>=counter)
{
printf("Ogiltig position\n");
}
else
{
printf("%s %d %s %s %s\n", reg[val].owner.name, reg[val].owner.age, reg[val].type, reg[val].brand, reg[val].regnum);
}
}
If additional information about my program is needed to solve the program please tell me and I will provide more of the code.
In this function, I am displaying a .txt document to the screen, which works, however, I am trying to read the file document and scan the document for the word EMPTY as I have it saved as a string variable. It should be noted that I am counting the time EMPTY is in the file and later printing the times it was would in the file along with on another thing. My first question is am I doing this correct?
void allSeats(void)
{
int position = 0;
int count = 0;
char gone[6] = "EMPTY";
system("cls");
retry:
fseatArrangement = fopen("airlineSeatingArrangment.txt", "r");
while (fgets(econoAirSeatArrangement, 1000, fseatArrangement) != NULL)
printf(econoAirSeatArrangement);
fclose(fseatArrangement);
while (count < FULL)
{
fgets(econoAirSeatArrangement, 1000, fseatArrangement);
fscanf(fseatArrangement,"%s", &gone);
count++;
}
printf("There are %d seats vacant at the moment\nThere are %d seats with no vacancy at the moment \n",count, FULL-count);
printf("Enter Zero(0) Key to return to menu at anytime.");
scanf("%d", &position);
if (position == 0)
{
system("cls");
menu();
}
else
{
system("cls");
printf("INVALID INPUT! Please try again.\n");
goto retry;
}
system("pause");
return;
}
The main problem is here
fgets(econoAirSeatArrangement, 1000, fseatArrangement);
you have already closed the file pointer using fclose(), and yet, you try to use it. It causes undefined behavior.
That said,
printf(econoAirSeatArrangement); appears wrong. If you do not wish to have any format conversion specification you can stick to puts().
You must check the return value of fopen(), fgets(), fscanf() etc. for success before using the returned value / scanned value.
What I want to do is to write n(taken from user) elements to a file.Then read the elements again to an array and sort them and again write them in another file.
Finally open that file and display its contents.
But the code seems not to work, all syntax, grammar etc is checked what's the error??
#include<stdio.h>
struct data
{
int a,ar[100];
}e;
int main()
{ FILE *f1,*f2;
int i,j,n,t;
printf("\nEnter Array Size:");
scanf("%d",&n);
f1=fopen("Array.txt","w");
for(i=0;i<n;i++)
{ printf("\nEnter %d element:",i+1);
scanf("%d",&e.a);
fprintf(f1,"%d",e.a);
}
fflush(stdin);
fclose(f1);
rewind(f1);
i=0;
f1=fopen("Array.txt","r");
while((fscanf(f1,"%d",&e.ar[i++]))!=EOF)
{}
fclose(f1);
for(i=0;i<n;i++)
{ for(j=0;j<n-1;j++)
{ if(e.ar[j]>e.ar[j+1])
{ t=e.ar[j];
e.ar[j]=e.ar[j+1];
e.ar[j+1]=t;
}
}
}
f2=fopen("Sort.txt","w");
i=0;
while((fprintf(f2,"%d",e.ar[i]))!=EOF)
{ i++;}
fclose(f2);
f2=fopen("Sort.txt","r");
while((fscanf(f2,"%d",&e.a))!=EOF)
{ printf("%d ",e.a);
}
fclose(f2);
return 0;
}
So you want to know the error? I found a HUGE one.
As I was running your program, I have determined a segmentation fault occurs after this line:
f2=fopen("Sort.txt","w");
The major error here is that you opened a file for writing data to it, but you're making a rather confusing loop.
This is your code:
i=0;
while((fprintf(f2,"%d",e.ar[i]))!=EOF)
{ i++;}
In the state it is in, the value of i will exceed the upper bound value of your ar int array. You set the upper bound value to 100, but in the while loop, it will run endlessly until segmentation fault happens (when i goes past 100) because fprintf will never return an EOF (according to what the linux manual on fprintf claims).
What I would suggest instead is this:
for(i=0;i<n;i++){
fprintf(f2,"%d",e.ar[i]);
}
where n is the number of elements to finally print (as indicated by user at beginning of the program).
So here is my code:
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#define MAX_GUESSES 4
int PlayGame(char guess);
int WinOrLose(char userguess, char solution);
int main()
{
FILE* infile;
char correctlet;
int games,
igame,
result;
infile = fopen("inputLet.txt", "r");
printf ("Welcome to the letter guessing game!\n");
printf ("Your job is to guess a random letter.\n");
printf("You can guess each letter a maximum of 4 times,\n");
printf ("and you will get a hint after every guess.\n");
printf ("LET'S DO THIS!\n\n>");
printf ("\nHow many games would you like to play (1-3)?\n>");
scanf ("%d",&games);
for(igame=0;igame<games;igame++)
{
fscanf(infile," %c",&correctlet);
printf("This is game %d\n", igame+1);
result = PlayGame (correctlet);
if (result == 0)
{
printf ("\nCongratulations, you guessed the right letter!\n");
}
else
{
printf ("\nUnfortunately, you did not guess the right letter. Better luck next time!\n");
}
}
return 0;
}
int PlayGame(char solution)
{
int guessnumber,
result;
char userguess;
guessnumber = 0;
while(guessnumber < MAX_GUESSES)
{
printf("Please enter your guess\n>");
scanf("%c", &userguess);
if (sizeof userguess == 0)
{
continue;
}
else if (sizeof userguess >=1)
{
printf ("Your guess was %c\n",userguess);
result = WinOrLose (userguess, solution);
if (result == 0)
{
return 0;
break;
}
else if (result == 1)
{
if (solution < userguess)
{
printf("The correct letter comes before %c alphabetically\n", userguess);
}
else if (solution > userguess)
{
printf("The correct letter comes after %c alphabetically\n", userguess);
}
guessnumber ++;
}
}
}
}
int WinOrLose (char userguess, char solution)
{
if(solution==userguess)
{
return 0;
}
else if (solution != userguess)
{
return 1;
}
}
The output asks for the number of games, and then it outputs please enter your guess your guess was (blank) The correct letter comes after (blank) Please enter your guess and THEN it allows for user input. So why is it going through one iteration of PlayGame without asking for user input? I have tried everything I can think of and can't fix the problem. I am compiling on VC++ 2010, if that helps.
Thanks in advance!
The simple answer is to flush your buffers.
The stdin buffer, the buffer that takes instructions from the keyboard (or a pipe) and submits it to the program occasionally gets some characters "stuck" in it. Junk characters that never quite get submitted, extra returns, etc. that will cause scanf() to think it reached the proper end, but actually hasn't.
fflush(stdin);
The function fflush "flushes" a buffer. The effect of this is to consume data from a buffer until the data received is the character '\0' (NULL). This means that it's reached the last of the data that is currently in the buffer.
Calling this before calling scanf() means that when scanf() is called, you reasonably know that the program will block on scanf() until you've submitted, and not just consume some junk from the buffer.