I have this code and it keeps adding what ever the guesses string is to the wordle string when I compare them, resulting in them to never be the same. How can I fix this?
#include <string.h>
int main() {
char wordle[5];
char guesses[5];
int guess = 5;
int value;
printf("Please input a secret 5 letter word:\n");
scanf("%s",wordle);
while (guess != 0){
printf("You have %d tries, please guess the word\n",guess);
scanf("%s",guesses);
value = strcmp(wordle,guesses);
if (value == 0){
printf("you win\n");
break;
}
guess = guess - 1;
}
return 0;
}```
Your program has undefined behavior. You're making two mistakes.
If your user enters 5 characters, it takes 6 characters to store the string. The program would attempt to write a null terminator into wordle[5] which is not a valid index.
Your user could enter any number of letters. You need to make sure they don't overflow your buffer.
#include <stdio.h>
#include <string.h>
int main() {
char wordle[6];
char guesses[6];
int guess = 5;
int value;
int chars_read;
do {
printf("Please input a secret 5 letter word:\n");
chars_read = scanf("%5s%*s\n", wordle);
} while(chars_read != 1 && strlen(wordle) != 5);
while (guess != 0){
do {
printf("You have %d tries, please guess the word\n", guess);
chars_read = scanf("%5s%*s\n", guesses);
} while(chars_read != 1 && strlen(wordle) != 5);
value = strcmp(wordle, guesses);
if (value == 0){
printf("you win\n");
break;
}
guess = guess - 1;
}
return 0;
}
See it in action
scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s
MSC24-C. Do not use deprecated or obsolescent functions
Your strings for wordle and guesses are too short. You need to make room for '\0'. They should be 6 bytes long not 5.
char wordle[6];
char guesses[6];
Related
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;
}
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.
I would appreciate some help with this. I'm trying to create this simple program that repeatedly loops asking for the user to enter in an int. If he enters an int, it exits but if he enters something else or bigger than int (ex.4gs4r33) it will loop again asking to enter an int. This is what I have tried, and it's not working. It says it's an int even if it's not.
#include<stdio.h>
unsigned int findInt();
int main() {
printf("Please input an int.\n");
findInt();
}
unsigned int findInt() {
char input;
long num = 0;
int b = 0;
do {
scanf("%c", &input);
if (isdigit(input)){
num = num*10+input+'0';
b = 1;
}
else if (input == '\n')
b = 1;
else
b = 0;
} while(input != '\n');
if (b == 1)
printf("Great!\n");
else{
printf("Not an int \n");
findInt();
}
return 0;
}
Two possible approaches. One would be to modify your code:
b = 1; // start off with good intentions…
do {
scanf("%c", &input);
if (isdigit(input)){
num = num*10+input -'0'; // *** SUBTRACT '0', don't add it!
}
else if (input != '\n') {
b = 0;
break; // *** break when you find non-digit
}
} while (input != '\n');
Two changes: getting the math right as you compute the integer, and fixing the logic (so you break out of your loop when you find a non digit character)
Second approach:
char buf[100];
char intAsString[100];
fgets(buf, 100, stdin);
sscanf(buf, "%d", num);
sprintf(intAsString, "%d\n", num);;
if(strcmp(buf, intAsString) == 0 ) {
printf("yay - you entered an integer!\n");
}
I'm sure you can figure out how that works.
update a complete code snippet that solves the issue of "loop logic" as well: you call the findInt function once from the top level, and it keeps going until you get the int. Note - in order for this to work properly, I read the entire input at once (rather than one at a time), then pick off the characters one by one using sscanf (and updating the pointer manually). It has a number of advantages - not least of which is that you start with a fresh input every time you call findInt, instead of having the rest of the input buffer that still needs reading (and which was giving rise to "no,no,no,great!" - as you would keep reading the bad input until you got to the newline, and accept that...)
#include<stdio.h>
#include <ctype.h>
unsigned int findInt();
int main() {
findInt();
}
unsigned int findInt() {
char input;
char buf[100];
char *temp;
long num = 0;
int b = 0;
printf("please enter an int:\n");
fgets(buf, 100, stdin);
temp = buf;
do {
sscanf(temp++, "%c", &input);
if (isdigit(input)){
num = num*10+input-'0';
b = 1;
}
else if (input == '\n')
{
b = 1;
break;
}
else {
b = 0;
break;
}
} while(input != '\n');
if (b == 1)
printf("Great! %d is an integer!\n", num);
else{
printf("Not an int \n");
findInt();
}
return 0;
}
In the else branch - i.e. not a digit or a newline - you set b to 0. Now if a digit DOES follow you reset that to 1.
You'll probably want to break or somehow record the permanent failure instead of just continuing.
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
void findInt(){
int x;
bool ok;
do{
char buff[32], *endp;
long long num;
ok = true;//start true(OK)
printf("Enter a number: ");
fgets(buff, sizeof(buff), stdin);
//strtoll : C99
x=(int)(num=strtoll(buff, &endp, 0));//0: number literal of C. 10 : decimal number.
if(*endp != '\n'){
if(*endp == '\0'){
printf("Too large!\n");//buffer over
while('\n'!=getchar());
} else {
printf("Character that can't be interpreted as a number has been entered.\n");
printf("%s", buff);
printf("%*s^\n", (int)(endp - buff), "");
}
ok = false;
} else if(num > INT_MAX){
printf("Too large!\n");
ok = false;
} else if(num < INT_MIN){
printf("Too small!\n");
ok = false;
}
}while(!ok);
}
,
My aim is to accept 4-digit numbers, and 4-character strings (string should not contain digits or special characters)
If an invalid input is given the program should not terminate and it must allow the user to enter the details and continue until he wish to terminate.
I am able to find whether the input is a digit.
if(scanf("%d",&input)!=1)
{
printf("enter the number please");
... // I have option to re enter using while and flags
}
else
{
// I continue my work
...
}
To check it is four digits I have tried using the commands
i=0;
num = input;
while(num>0)
{
i = i+1;
num = num/10;
}
if(i==4){
...//I continue
}
else
printf("please enter four digit");
I have no idea of checking the same for characters. (I know how to check its length using strlen())
Please help me with the code in C. (Also help me to reduce/optimize the above logic to check whether the input is a 4-digit number)
I believe you want 2 inputs a number and a string. You can do that as
int number= 0;
char string[10] = { 0 };
do {
printf("please enter four digit");
scanf("%d", &number);
if(number >=1000 && number<= 9999)
break;
} while(1);
do {
printf("please enter four character string");
fgets(string, sizeof(string), stdin);
if(strlen(string) == 4)
break;
} while(1);
To check it is four digit number you can simply put a check whether the number lies between 1000 and 9999. (I am assuming you don't want the number to start with 0.)
strtol can help:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s[32], *p;
int x;
fgets(s, sizeof(s), stdin);
if ((p = strchr(s, '\n')) != NULL)
*p = '\0';
x = (int)strtol(s, &p, 10);
if ((p - s) == 4) {
printf("%d\n", x);
} else {
printf("Please enter four digit\n");
}
return 0;
}
char input[16];
int ok = 1, k = 0;
if (scanf("%s", input) > 0 && strlen(input) == 4) {
// check if it's a word
for (; k < 4; k++)
if (!isalpha(input[k])) {
// check if it's a number
for (int k = 0; k < 4; k++)
if (!isdigit(input[k]))
ok = 0;
break;
}
}
else ok = 0;
if (!ok)
printf("invalid input, please enter a 4-digit number or 4-letter word");
else {
printf("valid input");
...
}
You can use gets()1 fgets() to get the whole line and check line length. If the first character is between '0' and '9' then check the remaining if they are 3 numbers too. If the first character is a valid character in string then check the 3 remaining chars if it's also valid in string.
1See Why is the gets function so dangerous that it should not be used?
I'm writing a program in C that is suppose to ask the user for a number.
The number has to be greater than zero and cannot have letters before or after the number. (ie: 400 is valid but abc or 400abc or abc400 is not). I can make my program invalidate everything besides 400abc. How would I make it invalidate an input if it starts valid then turns invalid? (I'm about 2 months into an intro to c class so my knowledge is very limited.)
#include<stdio.h>
int check(void);
void clear_input(void);
main()
{
int num;
printf("Please enter a number: ");
num = check();
printf("In Main %d\n", num);
}
int check(void){
int c;
scanf("%d", &c);
while (c < 0){
clear_input();
printf("Invalid, please enter an integer: ");
scanf("%d", &c);
}
return c;
}
void clear_input(void){
char junk;
do{
scanf("%c", &junk);
}while (junk != '\n');
}
You can also check whether ascii value of each char scanned from user input should lie in range 48-57, It will only then be integer value.
strtol can be used to do it, but it takes some extra work.
After running this code:
char *endptr;
int n = strtol(num_text, &endptr, 10);
n will contain the number. But you still have to check that:
1. *endptr=='\0' - this means strtol didn't stop in the middle. In 400abc, endptr will point to abc. You may want to allow trailing whitespace (in this case, check that endptr points to an all-whitespace string.
2. num_text isn't empty. In this case, strtol will return 0, but an empty string isn't a valid number.
Read the input as a line, using fgets.
Check if all characters are numeric.
If not, it's invalid. If yes, use sscanf to get the line into an int.
Check if the int is in the range; you're done.
Scanf with %d will treat the "400abc" as 400, all the trailing characters would be ignored, so there is nothing to worry about.
If you definitely want to treat "400abc" as an invalid input, then maybe you shouldn't use %d in scanf, use %s instead?
One way is to read the whole line as a string and check by yourself if it contains any non-digits.
The other way is reading the integer and then looking into the input using fgetc() to see if the next character after the detected input is valid. Or you could even use the same scanf() for this:
char delim;
if(scanf("%d%c", &c, &delim) == 2 && !isspace(delim))
// the input is invalid
You can read the number in a character array and validate it by checking if all the characters lie in the ascii range 48 to 57 ( '0' to '9' ) .If so your no. is valid otherwise you can safely regard it as invalid input.Here the the demonstration :
#include<stdio.h>
#include<string.h>
int conv( char * word )
{
int ans=0;
int res=0;
for(int i=0;i<strlen(word);i++)
if(word[i]>='0' && word[i]<='9')
ans=(ans*10) + (word[i] - '0');
else
res=-999;
if(res==-999)
return res;
else
return ans;
}
int main()
{
char a[10];
gets(a);
int b=conv(a);
if(b==-999)
printf("Invalid Entry.\n");
else
printf("Success.No is %d.\n",b);
return 0;
}
You can adjust for negatives as well by checking the first character in the word array to be '-' and adjusting the sign accordingly.
This is C99, so compile with -std=c99
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
bool getNum(int *n) {
char c, s[10];
if (!scanf("%9s", s))
return false;
for (int i=0; c=s[i]; i++)
if (!isdigit(c))
return false;
*n = atoi(s);
return true;
}
int main() {
int n;
if (getNum(&n))
printf("you entered %d\n", n);
else
printf("you did not enter a number\n");
}
The following is your check function rewritten to fix your problem, so try this:
int check(void){
int n;
char c;
while (EOF==scanf("%d%c", &n,&c) || n < 0 || !isspace(c)){
clear_input();
printf("Invalid, please enter an integer: ");
}
return n;
}