IO in C standard - c

The following program is from a homework assignment.
I need to write a program where it:
asks a Seed and a Range,
generates and displays a sequence of random numbers based on the seed and range input,
converts the above into a sequence of "A"s, "B"s, or "C"s depending on the generated sequence: turn 1 into A, 2 into B, 3 into C;
asks whether to continue; if user puts "n", stop; else starts over again.
#include <stdlib.h>
#include <stdio.h>
int main() {
int seed;
int Range;
char ch;
while (ch != "n") {
printf("Enter a seed: ");
scanf("%d", &seed);
printf("Enter a Range: ");
scanf("%d", &Range);
srand(seed);
for (int i = 0; i < 10; i++) {
scheduler(rand() % Range + 1);
}
printf("Continue?\n");
scanf("%c", &ch);
}
return 0;
}
I put two arbitrary numbers and it generates a random sequence as expected. But then it just prints "Continue?" without taking an input from me and then asks me to enter a seed. What's wrong with my code? What's the proper way to do this?

Change this:
scanf("%c", &ch);
to this:
scanf(" %c", &ch);
in order to eat the leftover character (the newline character you pressed when you entered the numbers (seed andRange`) before).
I had wrote more about that issue here.
Moreover, your code invokes Undefined Behavior (UB), since you check ch before it gets initialized here:
char ch;
while (ch != "n") {
...
}
Use a do-while loop structure instead, like this:
do {
...
} while (ch != 'n');
Furthermore, you should get a compiler warning like this:
warning: comparison between pointer and integer
while (ch != "n") {
^~
warning: comparison with string literal results in unspecified behavior [-Waddress]
Change "n" to 'n', since ch is of type char, not char*.
Putting everything together, your code should like this:
#include <stdlib.h>
#include <stdio.h>
int main() {
int seed;
int Range;
char ch;
do {
printf("Enter a seed: ");
scanf("%d", &seed);
printf("Enter a Range: ");
scanf("%d", &Range);
srand(seed);
for (int i = 0; i < 10; i++) {
scheduler(rand() % Range + 1);
}
printf("Continue?\n");
scanf(" %c", &ch);
} while (ch != 'n');
return 0;
}

#include <stdlib.h>
#include <stdio.h>
int main()
{
int seed;
int Range;
char ch = '\0'; /* initialize ch to something other than 'n' */
/* if ch not initialized, u take your chances on being able to enter while loop */
while (ch != 'n') / single quote characters, double quote for strings imply null character \0 after last character in string */
{
printf("Enter a seed: ");
fflush( stdout ); /* because of no \n in printf */
scanf("%d", &seed);
printf("Enter a Range: ");
fflush( stdout ); /* because of no \n in printf */
scanf("%d", &Range);
srand(seed);
for (int i = 0; i < 10; i++)
{
scheduler(rand() % Range + 1);
}
printf("Continue?\n"); /* bet u this works, because of \n */
scanf("%c", &ch);
}
return 0;
}

Related

Making sure the input is a charachter

This might be a rookie question, but I need to make sure that the input given by the user is of data type char [%c] or a string [%s].
If it were an integer, I would just do something like this:
int data, x;
do {
printf("Please enter a number: ");
x = scanf(" %d", &data);
getchar();
} while(x!=1);
So I was wondering if there's a similar way to do this, if the input is supposed to be a string or a character. Thanks, Any help would be appreciated!
Avoid to use %c in scanf() because some unexpected character like \r\n will be input.
You can use a char[2] to receive a single character. An \0 will be filled after your string to represent the end of string, so the length of array must be bigger than 1.
An example:
#include <stdio.h>
int main()
{
char data[2];
scanf("%1s", data);
if (data[0] >= 'a' && data[0] <= 'z') // custom your constraint here
{
// legal
printf("legal: %s", data);
}
else
{
// illegal
printf("illegal: %s", data);
}
return 0;
}
While I input b, the data will be "b\0".
part of the answer is if you just want to read only alphabet you can use below.
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch;
do {
printf("enter a char:");
scanf(" %c",&ch);
}while(!isalpha(ch));
printf("%c",ch);
return 0;
}
Update 1:
Just for the completeness and for the FUN part of the programing, have added code here.
This works well (not tested robustly, you can do if you need to) for the single char input or for a string of length 9.
Remember to type the EOF after input is entered in case length of input is < 9.
and read EOF behavior on same line and new line.
#include <stdio.h>
#include <ctype.h>
#define LEN 10
int main()
{
char ch;
char str[LEN] = {0};
int i = 0;
int ret;
printf("enter a char or string(len = 9) and press EOF if len < 9\n");
do {
if(1== (ret = scanf(" %c",&ch)))
{
if(isalpha(ch))
str[i++] = ch;
}
else
printf("scanf:Error (%d)\n", ret);
}while(ret != EOF && ( !isalpha(ch) || i < LEN-1));
str[i] = '\0';
printf("str is %s\n",str);
return 0;
}

Getting a different value than expected runs in a loop. Why?

So, this program accepts three values, an int, a float and a char while being inside a loop.
When it asks the user to enter the integer and they write.. let's say, "House" the program falls in an infinite loop.
#include <stdio.h>
int main(void){
int i;
float f;
char c;
while(i!=99){
printf("Enter an int, a float and a char separated by commas: ");
int count = scanf("%d,%f,%c",&i,&f,&c);
printf("Int is: %d, Float is: %1.f, Char is: %c",i,f,c);
if (count != 2){
fflush(stdin);
printf("\nerror\n");
}
}
return 0;
}
scanf() leave characters which aren't interpreted as data to read, so in next iteration, scanf() try to read the characters again and fail again, then it will cause endless loop.
fflush(stdin); is undefined behavior and do not use it.
Uninitialized i is used in i!=99, which is also undefined behavior.
Try this:
#include <stdio.h>
int main(void){
int i=0;
float f=0.0f;
char c=' ';
while(i!=99){
printf("Enter an int, a float and a char separated by commas: ");
int count = scanf("%d,%f,%c",&i,&f,&c);
printf("Int is: %d, Float is: %1.f, Char is: %c",i,f,c);
if (count != 3){ /* adjusted to match the scanf */
int dummy;
while((dummy=getchar())!='\n' && dummy!=EOF); /* skip one line */
printf("\nerror\n");
if (dummy == EOF) break; /* there won't be any more input... */
}
}
return 0;
}
In this -
if (count != 2){
fflush(stdin); // undefined behaviour
printf("\nerror\n");
}
Also count should be tested against 3 not 2 (scanf will return 3 if successfull ). Instead of fflush(stdin) , use this to clear input stream-
int c;
if (count != 3){
while((c=getchar())!='\n' && c!= EOF);
printf("\nerror\n");
}
Also you have i uninitialized. So ,either initialize it or instead of using while loop use do-while -
do{
//your code
}while(i!=99);

Program help! After user hits enter the program ends

Ok I am making a program that reads two characters from the user and then prints the ASCII letters between those two characters.
The problem is that when the program runs it prompts the user to enter the first character and once the user hits enter the program ends.
What am I missing?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
char firstchar;
char secondchar;
int variable;
int highest;
int lowest;
char ASCIvariable;
printf("Please enter a character. ");
scanf("%d", &firstchar);
printf("Please enter another character. ");
scanf("%d", &secondchar);
if(firstchar < secondchar)
{
secondchar = highest;
firstchar = lowest;
}else{
firstchar = highest;
secondchar = lowest;
}
variable = lowest;
for ( variable != highest; variable < highest; variable++ )
{
variable = ASCIvariable;
printf(ASCIvariable);
}
return 0;
}
I clearly also don't understand how to post code on this site. I need four spaces manually entered before EVERY line of code?
Update here is the current code also control k will not allow paste....
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char firstchar;
char secondchar;
int variable;
int highest;
int lowest;
char ASCIvariable;
printf("Please enter a character. ");
scanf(" %c", &firstchar);
printf("Please enter another character. ");
scanf(" %c", &secondchar);
if(firstchar < secondchar)
{
highest = secondchar;
lowest = firstchar;
}
else
{
highest = firstchar;
lowest = secondchar;
}
variable = lowest;
for (variable != highest; variable <= highest; variable++ )
{
ASCIvariable = variable;
printf("%c ", ASCIvariable);
}
return 0;
}
It successfully allows the user to enter both characters and then prints the letters between the two. I think that is correct?
Using wrong format specifier might lead to UB. You need to scan a character
scanf("%c", &firstchar);
Then flush the newline char using
scanf(" %c",&secondchar);
The space before the %c consumes the newline char.
1)You must get input with format specifier %c for characters
2)You must consume the newline after entering first character
3) You seem to be confused with assignment statements
a=b
assigns the valure of b to a and not the other way around.
printf("Please enter a character. ");
scanf(" %c", &firstchar);
//The space before %c will consume the newline
printf("Please enter another character. ");
scanf(" %c", &secondchar);
if(firstchar < secondchar)
{
highest=secondchar ;
lowest=firstchar ;
}
else
{
highest=firstchar;
lowest= secondchar ;
}
//Changed the for loop to get characters between two inputs
variable = lowest+1;
for ( ; variable < highest; variable++ )
{
ASCIvariable= variable ;
printf("%c ", ASCIvariable);
}
Change your code to:
printf("Please enter another character. ");
scanf(" %c", &secondchar); /* Note the extra space and %d is changed to %c*/
Also change your for loop to:
for ( ; variable <= highest; variable++ ) /* Should be <= */ {
ASCIvariable = variable; /* Reverse */
printf("%c", ASCIvariable); /* %c */
}
Your assignations are also incorrect:
if(firstchar < secondchar)
{
highest = secondchar;
lowest = firstchar;
}
else
{
highest = firstchar;
lowest = secondchar;
}
a = b; means copy contents of b into a.

Input several numbers from array and each one number check for integer or not

everyone!
I hope someone can help me figure out something in C language.
This is my first seriously homework in IT, I have no experience and I'm learning in e-studies, so teacher help isn't very available.
I need to develop console application in C language. User need to input 10 integer numbers, if insert number isn't integer, need to output error and again re-enter new number until all 10 integer numbers will be inserted.
Everything works in case if I say that these 10 numbers can't be 0 (I make this to be sure that my if-else statement working), but won't work when I want that every input number will be check if it is integer or not.
How can I do it right.
Please help
so far my code look like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
float f;
int numbers[10];
for (i = 0; i < 10; i++)
{
scanf ("%d", &numbers[i]);
if (numbers[i] != 0)
{
scanf ("*%d", &numbers[i]);
}
else
{
printf ("\nError!Entered number is't integer \n");
printf ("\nPlease insert number again \n");
scanf("%*d", &numbers[i]);
}
}
}
#include <stdio.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
val = scanf("%d", numbers + i); // read the integer into a[i]
if(val != 1) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
val = scanf("%d", numbers + i);
continue;
}
++i;
}
// process the numbers array
return 0;
}
I write this line again
val = scanf("%d", numbers + i);
Now it works how I need. Great - thanks a lot
There are several techniques you might use:
Read the number as a string and reject if it contains characters not suitable for an integer. The use sscanf() to convert the string to integer.
Read the number as a float and reject if it is out of integer range or it has a non-integer value.
Read the input character by character and build up an integer value. If invalid characters appear, reject the value.
scanf returns the number of input items successfully matched and assigned. You can check this value for 1 for each call of scanf. If the value is 0, then you should discard the input to clear the stdin buffer and read input again.
#include <stdio.h>
#include <ctype.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
// read an integer and the first non-numeric character
val = scanf("%d%c", numbers + i, &ch);
// if the number of items assigned by scanf is not 2 or if
// the first non-numeric character is not a whitespace, then
// discard the input and call read input again.
// for example input of type 32ws are completely discarded
if(val != 2 || !isspace(ch)) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
++i;
}
// process the numbers array
return 0;
}
Although I am not entirely clear on the details of your question, here is an outline of code similar to what you want:
int main(void)
{
int i;
int numbers[10];
int sum = 0;
for(i=0; i<10; ++i)
{
printf("Enter #%d:\n", i+1);
scanf("%d", numbers+i);
if (numbers[i] % 2 == 0) // Then Number is even
{
sum += numbers[i];
}
}
printf("The sum of only the even numbers is %d\n", sum);
getch();
return 0;
}
To read an int, suggest fgets() then sscanf() or strtol()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int numbers[10];
for (i = 0; i < 10; ) {
char buffer[50];
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
int n; // number of `char` parsed
if (sscanf(buffer, "%d %n", &numbers[i], &n) != 1 || buffer[n] != '\0') {
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
i++;
}
return 0;
}
The strtol() approach. This detects overflow issues:
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
char *endptr;
errno = 0;
long num = strtol(buffer, &endptr, 10);
if (errno || num < INT_MIN || num > INT_MAX) Handle_RangeError();
if (buffer == endptr || *endptr != '\n') Handle_SyntaxError();
numbers[i] = (int) num;
Recommend making a int GetInt(const char *prompt) function that can be used repeatedly.
User input is evil. Do not trust it until well vetted.

Converting string value to int equivalent in C

Can someone tell me what's wrong with this:
int main()
{
char a[100];
int i = 0;
printf("Enter a number: ");
scanf("%c", &a[i]);
printf("The number you've entered is: %d", a[i] - '0');
}
Brief summary: I am trying to convert a number stored in a char array to its int equivalent. I know in C#, you use the intparse command, but because there isn't such one in C, I do not know what to do. When I input a two digit number, it is only outputting the first digit, of the input char.
strtol sample
#include <stdio.h>
#include <stdlib.h>
int main(){
char str[16], *endp;
int value;
printf("Enter a number: ");
fgets(str, sizeof(str), stdin);
value = strtol(str, &endp, 0);
if(*endp == '\n' || *endp == '\0'){
printf("The number you've entered is: %d\n", value);
} else {
printf("invalid number format!");
}
return 0;
}
If you mean to print ASCII value of char the no need to do a[i] - '0'.
Try this
printf("The number you've entered is: %d", a[i]);
If you are talking about string then first change your scanf statement to
scanf("%s", a);
or better to use fgets library function instead of scanf;
fgets(a, sizeof(a), stdin);
and then use strtol function.
OP method of scanf("%c", &a[i]); only handles a 1 character input.
To read the entire line, suggest using fgets() to read.
The convert to a long using strtol().
Watch for potential errors.
#include <stdio.h>
#include <stdlib.h>
int main(){
// use long to match strtol()
long i;
// size buffer to handle any legitimate input
char a[sizeof i * 3 + 3];
char *endptr;
printf("Enter a number: ");
if (fgets(a, sizeof a, stdin) == NULL) {
// If you would like to handle uncommon events ...
puts("EOForIOError");
return 1;
}
errno = 0;
i = strtol(str, &endptr, 10);
if(*endptr != '\n' /* text after number */ ||
endp == a /* no text */ ||
errno /* overflow */) {
printf("Invalid number %s", a);
}
else {
printf("The number you've entered is: %ld\n", i);
}
return 0;
}
Try
char myarray[5] = {'-', '4', '9', '3', '\0'};
int i;
sscanf(myarray, "%d", &i); // i will be -493
Edit (borrowed from [1]):
There is a wonderful question here on the site that explains and compares 3 different ways to do it - atoi, sscanf and strtol. Also, there is a nice more-detailed insight into sscanf (actually, the whole family of *scanf functions).
#include<stdio.h>
#include<stdlib.h>
int main()
{
char a[100];
int final=0,integer;
int i;
printf("Enter a number: ");
gets(a);
for(i=0;a[i]>='0'&&a[i]<='9';++i)
{
integer=a[i] - '0';
final=final*10+integer;
}
enter code here
printf("The integer is %d ", final);
}

Resources