my programe gets 5 grades and calculates average and max values.but when i enter a letter first instead of a grade, it continuously prints "invalid". when i enter a letter after entering a int value it stops further getting remaining values.can someone explain where i am wrong? thank you
#include <stdio.h>
#include <stdlib.h>
int main()
{
int grade[5];
int temp;
int temp2 = 0;
for(int i = 0; i <= 4; i++) //getting inputs
{
printf("enter grade= ");
scanf("%i", &temp);
if(temp <= 100 && temp >= 0)
grade[i] = temp;
else
{
printf("invalid\n");
i--;
}
}
//print array
for(int i = 0; i <= 4; i++)
printf("%i\n", grade[i]);
//Average
for(int i = 0; i <= 4; i++)
{
temp2 = temp2 + grade[i];
}
printf("avg is= %i\n", temp2 / 5);
//Max
int mx = grade[0];
for(int i = 1; i <= 4; i++)
if(mx < grade[i])
{
mx = grade[i];
}
printf("max is= %i", mx);
return 0;
}
From the scanf man page:
These functions return the number of input items successfully
matched and assigned, which can be fewer than provided for, or
even zero in the event of an early matching failure.
So when the scan fails, you have to read and throw the offending characters, or it will still be in the buffer.
you can use the following macro instead of using scanf() directelly
#define SCAN_ONEENTRY_WITHCHECK(FORM,X,COND) \
do {\
char tmp;\
while(((scanf(" "FORM"%c",X,&tmp)!=2 || !isspace(tmp)) && !scanf("%*[^\n]"))\
|| !(COND)) {\
printf("Invalid input, please enter again: ");\
}\
} while(0)
and in your code you call the macro in this way
for(int i = 0; i <= 4; i++) //getting inputs
{
printf("enter grade= ");
SCAN_ONEENTRY_WITHCHECK("%i",&tmp,(temp <= 100 && temp >= 0));
grade[i] = temp;
}
for more details concerning the macro and concerning the reason of getting infinite loop in your code, please refer to Common macro to read input data and check its validity
Related
I'm trying to make a C program to insert elements into an array until user inputs a 0 or less number, as the title says. But when I print the array out, it doesn't show the numbers I inputted. I have tried using a while as well as do-while loops but without success.
#include <stdio.h>
int main() {
int data[100];
int i;
for (i = 0; i < 100; i++) {
printf("Input your number:\n");
scanf("%d", &data[i]);
if (data[i] <= 0) {
break;
}
}
printf("Your array:");
int n = sizeof(data[i]);
for (int i = 0; i < n; i++) {
printf("%d ", &data[i]);
}
}
Try this:
#include <stdio.h>
int main() {
int data[100];
int i;
int counter = 0;
for (i = 0; i < 100; i++) {
printf("Input your number:\n");
scanf("%d", &data[i]);
counter++;
if (data[i] <= 0) {
break;
}
}
printf("Your array:");
for (int j = 0; j < counter - 1; j++) {
printf("%d ", data[j]);
}
}
The problem was that you had printf("%d ", &data[i]); instead of printf("%d ", data[i]);.
And also you've trying to get the sizeof() of an element data[i], not the size of the whole array. That's why there's counter in my code.
int n = sizeof(data[i]);
this is wrong, you want
int n = i;
sizeof(data[i]) gives you the size of an int (4 on my machine)
On the other hand, you need to check the result of scanf, if a bad input is entered do not increment the counter, something like:
int i = 0;
while (i < 100)
{
int res = scanf("%d", &data[i]);
if (res == EOF)
{
break;
}
if (res == 1)
{
if (data[i] <= 0)
{
break;
}
i++;
}
else
{
// Sanitize stdin
int c;
while ((c = getchar()) != '\n');
}
}
Finally, scanf wants a pointer to the object, but this is not the case of printf:
printf("%d ", &data[i])
should be
printf("%d ", data[i])
Assigned task is to ask for # of values, and then at the end output the minimum, maximum, and average values and at this point I've run out of bug fixes
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
int ErrorDetection = 1;
char valCounter;
int valnumber;
int Incrementer;
int StoredValue;
int MinimumValue = 100;
int MaximumValue = 0;
float Average;
int AddToStored;
int Sum = 0;
printf("MIN, MAX, and MEAN CALCULATOR\n\n");
while (ErrorDetection != 0)
{
printf("How many values are to be entered?\n");
scanf("%s", &valCounter);
if (valCounter > '0' && valCounter < '9') {
ErrorDetection = 0;
}
else {
ErrorDetection = 1;
printf("INPUT ERROR!\n");
}
valCounter = valCounter - 47;
}
for (Incrementer = 1; Incrementer < valCounter; Incrementer++)
{
ErrorDetection = 1;
while (ErrorDetection != 0) {
printf("Value %d: ", Incrementer);
scanf(" %d", &StoredValue);
if (StoredValue > 0 && StoredValue < 9) {
ErrorDetection = 0;
}
else {
ErrorDetection = 1;
printf("INPUT ERROR!\n");
continue;
}
}
if (StoredValue > MaximumValue) {
MaximumValue = StoredValue;
}
if (StoredValue <= MinimumValue) {
MinimumValue = StoredValue;
}
Sum = Sum + StoredValue;
}
valCounter = valCounter - 1;
Average = (float)Sum / (float)valCounter;
printf(
"Minimum value is %d, maximum value is %d, and average value is %g.\n",
MinimumValue, MaximumValue, Average
);
}
If you input a 2 digit number things begin to breakdown, but at the same time I don't know how to go through with errorchecking if I allow multiple digit answers, as I make use of ASCII conversions to check if an input is a number or not.
You have undefined behavior here.
char valCounter;
scanf("%s", &valCounter);
You have declared valCounter as char type but trying to read string type.
Hence change the scanf to.
scanf("%c", &valCounter);
I would suggest you declare valCounter as int
int valCounter;
scanf("%d", &valCounter);
in that case your if will become.
if ((valCounter > 0) && (valCounter < 9))
and you don't need
valCounter = valCounter - 47; //remove
Also your for loop should start from 0 instead of 1
for(Incrementer = 1 ; Incrementer < valCounter; Incrementer++)
should be
for(Incrementer = 0 ; Incrementer < valCounter; Incrementer++)
Your problem is here.
char valCounter;
scanf("%s", &valCounter);
You're telling scanf to read a string, but you're passing it the address of a character. You should be asking for an integer, and giving it the address of an integer.
int valCounter;
scanf("%d", &valCounter)
There's more information here, including reasons why scanf might not be the best idea:
How to scanf only integer?
I'm having trouble outputting an invalid statement if the user inputs a letter instead of a number into a 2D array.
I tried using the isalpha function to check if the input is a number or a letter, but it gives me a segmentation fault. Not sure what's wrong any tips?
the following code is just the part that assigns the elements of the matrix.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main() {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
scanf("%d", &n);
if (n <= 1 || n >= 11) { // can't be bigger than a 10x10 matrix
printf("Invalid input.");
return 0;
}
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (!isalpha(matrix[i][j])) { // portion I'm having trouble with
continue;
} else {
printf("Invalid input.");
return 0;
}
}
}
...
As the value of n will be number, we can solve it using string instead of int.
char num[10];
int n;
scanf("%s", num);
if(num[0] < '0' || num[0] > '9' || strlen(num) > 2){
printf("invalid\n");
}
if(strlen(num) == 1) n = num[0] - '0';
if(strlen(num) == 2 && num[0] != 1 && num[1] != 0) printf("invalid\n");
else n = 10;
Also we can use strtol() function to convert the input string to number and then check for validity.You can check the following code for it. I have skipped the string input part. Also you have to add #include<stdlib.h> at the start for the strtol() function to work.
char *check;
long val = strtol (num, &check, 10);
if ((next == num) || (*check != '\0')) {
printf ("invalid\n");
}
if(val > 10 || val < 0) printf("invalid\n");
n = (int)val; //typecasting as strtol return long
You must check the return value of scanf(): It will tell you if the input was correctly converted according to the format string. scanf() returns the number of successful conversions, which should be 1 in your case. If the user types a letter, scanf() will return 0 and the target value will be left uninitialized. Detecting this situation and either aborting or restarting input is the callers responsibility.
Here is a modified version of your code that illustrates both possibilities:
#include <stdio.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main(void) {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
if (scanf("%d", &n) != 1 || n < 2 || n > 10) {
// can't be bigger than a 10x10 matrix nor smaller than 2x2
// aborting on invalid input
printf("Invalid input.");
return 1;
}
for (int i = 0; i < n; i++) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; j++) {
if (scanf("%d", &matrix[i][j]) != 1) {
// restarting on invalid input
int c;
while ((c = getchar()) != '\n') {
if (c == EOF) {
printf("unexpected end of file\n");
return 1;
}
}
printf("invalid input, try again.\n");
j--;
}
}
}
...
The isdigit() library function of stdlib in c can be used to check if the condition can be checked.
Try this:
if (isalpha (matrix[i][j])) {
printf ("Invalid input.");
return 0;
}
So if anyone in the future wants to know what I did. here is the code I used to fix the if statement. I am not expecting to put any elements greater than 10000 so if a letter or punctuation is inputted the number generated will be larger than this number. Hence the if (matrix[i][j] > 10000). May not be the fanciest way to do this, but it works and it's simple.
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (matrix[i][j] > 10000) { // portion "fixed"
printf("Invlaid input");
return 0;
}
}
}
I used a print statement to check the outputs of several letter and character inputs. The lowest out put is around and above 30000. So 10000 I think is a safe condition.
First I apologize for any mistype, for I am Brazilian and English is not my native language.
I am a freshman at my college and I got this algorithm to solve, from my teacher:
Make a program that creates a vector of n words, n being a size entered by the user (maximum 100). Your program should remove all duplicate words from the input vector and sort the words. Print the final vector without repeated and ordered words.
E.g. with 7 words to sort:
Input: 7 [enter]
hand ear leg hand hand leg foot
Output: ear foot hand leg
Note: Comment the program prints so that the output of the program is as shown in the example above (the numbers are separated by a spacebar, without space after last digit).
Note2: In case of invalid entry the program should print: "invalid entry" (all lower case).
Ok, I got it working but the I got confused with the notes and I can't find a way to fix the possible bugs, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100][100], aux[100];
int i, j, num;
printf("Type how many words you want to order: ");
do
{
scanf("%d", &num);
}while (num>100 || num<=0);
for(i=0; i<num; i++)
scanf("%s",&word[i]);
for (i = 0; i < num; i++) //loop to sort alphabetically
{
for (j = i+1; j < num; j++)
{
if ((strcasecmp(word[i], word[j]) > 0)) //swapping words
{
strcpy(aux, word[j]);
strcpy(word[j], word[i]);
strcpy(word[i], aux);
}
}
}
for (i = 0; i < num; i++) //loop to remove duplicates
{
if ((strcasecmp(word[i], word[i+1]) == 0)) //finding the duplicates
{
for (j = i+1; j < num; j++) //loop to delete it
strcpy(word[j], word[j+1]);
num--;
i--;
}
}
printf("\nWords sorted and without duplicates:\n");
for(i=0; i<num-1; i++)
printf("%s ", word[i]); //output with spacebar
printf("%s", word[num-1]); //last output without spacebar
return 0;
}
When I type a word with more than 100 characters, the Code::Blocks closes with an error, else it works fine. What do you think I should change?
The teacher uses a Online Judge (Sharif Judge) to evaluate if the code is right, and I got error in 3 of the tests (that are not specified), all of them were "Time Limit Exceeded". Maybe it has do to with the size of the matrix, or the problem with words >100.
Thanks in advance, Vinicius.
I guess you input sanity check is causing the issue.
As mentioned in the comment section.
If n is always < 100. Definitely your sorting is not causing any time limit exceeded.
Looks like the n is given something greater than 100 and your scanf is waiting and causing the issue. Also, make sure your input numbers are taken properly. If the input is > 100 print 'invalid entry'.
Something like below should work.
scanf("%d", &num);
if (num > 100)
printf("invalid entry");
for (i = 0; i < num; i++) {
scanf("%s", word[i]);
if (strlen(word[i])>100)
printf("invalid entry");
}
Hope it helps!
of course you will get an error if you use woerds more than 100 length casue you
have this line: char word[100][50], aux[100];
that means that you word length limit is set to 50. use word[100][100];
also you may not delete duplicates, just skip them in output
lol of course if youre using judge , you should not output any symbols except the answer, this means you should delete all lines, like :
printf("Type how many words you want to order: ");
and check the input format, and check limitations, i mean max word length , max amounts of words
try smth like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max_word_length = 101;
#define max_amount_of_words = 101;
int main() {
char word[max_amount_of_words][max_word_length] = {};
char aux[max_word_length];
int i, j, num;
scanf("%d", &num);
if (num < 0 || num > 100) {
printf("invalid entry");
return 0;
}
for (i = 0; i < num; i++) {
scanf("%s", word[i]);
}
for (i = 0; i < num; i++) {//loop to sort alphabetically
for (j = i + 1; j < num; j++) {
if ((strcasecmp(word[i], word[j]) > 0)) { //swapping words
strcpy(aux, word[j]);
strcpy(word[j], word[i]);
strcpy(word[i], aux);
}
}
}
bool is_joint = false;
for (i = 0; i < num; i++) { //loop to skip duplicates
if ((strcasecmp(word[i], word[i + 1]) != 0)) { //if there is a duplicate , we willnot output it
if(is_joint) printf(" ");
printf("%s ", word[i]);
is_joint = true;
}
}
return 0;
}
I got 100% on Judge, I fixed the code and looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char word[101][101],aux[101]; //a number higher than the limit to comparisons
int i,j,num;
scanf("%d",&num);
if(num<=0||num>100){ // if words < 0 or >100
printf("invalid input");
return 0;
}
for(i=0;i<num;i++){
scanf("%s",&word[i]); //read n words
if(strlen(word[i])>100){ //if word >100 caracters
printf("invalid input");
return 0;
}
for(j=0;j<strlen(word[i]);j++){
if (word[i][j]>=65&&word[i][j]<=90){
word[i][j]= word[i][j]+32; // if word is uppercase, make them lowcase
}
else if (word[i][j]>122||word[i][j]<97){// if word is different from alphabet lowercase
printf("invalid input");
return 0;
}
}
}
for(i=0;i<num;i++){
for(j=i+1;j<num;j++){
if((strcmp(word[i],word[j])>0)){ //loop to sort words
strcpy(aux,word[j]);
strcpy(word[j],word[i]);
strcpy(word[i],aux);
}
}
}
for(i=0;i<num-1;i++){
if((strcmp(word[i],word[i+1])!=0)){ // output words with spacebar, without the last one
printf("%s ",word[i]);
}
}
printf("%s",word[num-1]); // last word without spacebar
return 0;
}
Thank you everyone who tried to help, I've learned a lot with your suggestions!
This project is actually pretty tough assignment for a programmer who just
started in C.
Run this program in your computer.
Before running against the Judge, make sure you run many times with your manual inputs. Once you are happy with the tests, try against the Judge.
Like I said, the hardest part is storing the user's inputs according to spec (accepting space or newline characters in multiple lines).
#include <stdio.h>
#include <string.h>
int
main(void)
{
int iNumW, iIndex;
int iWCnt = 0;
int iC;
char caTemp[100];
char caWords[100][100];
char *cpDelimeter = " \n";
char *cpToken;
char *cp;
short sIsWord = 1;
char caGarbage[100];
scanf("%d", &iNumW );
fgets(caGarbage, sizeof caGarbage, stdin); //Remove newline char
//Get word inputs
while( iWCnt < iNumW )
{
fgets(caTemp, sizeof caTemp, stdin );
for( cpToken = strtok( caTemp, cpDelimeter ); cpToken != NULL; cpToken = strtok( NULL, cpDelimeter)){
cp = cpToken;
while( *cp ){
sIsWord = 1;
//Check if alphabet
if( !isalpha(*cp) ){
sIsWord = 0;
break;
}
cp++;
}
if( sIsWord ){
strcpy( caWords[iWCnt], cpToken );
//printf( "%s\n", caWords[iWCnt]);
iWCnt++;
if( iWCnt >= iNumW ) break;
} else {
printf("invalid entry.\n");
}
//printf("%d\n", iWCnt);
}
}
int i,j ;
for (i = 0; i < iWCnt; i++) {//loop to sort alphabetically
for (j = i + 1; j < iWCnt; j++) {
if ((strcasecmp(caWords[i], caWords[j]) > 0)) { //swapping words
strcpy(caTemp, caWords[j]);
strcpy(caWords[j], caWords[i]);
strcpy(caWords[i], caTemp);
}
}
}
for (i = 0; i < iWCnt; i++) { //loop to skip duplicates
if ((strcasecmp(caWords[i], caWords[i + 1]) != 0)) { //if there is a duplicate , we willnot output it
printf("%s ", caWords[i]);
}
}
return 0;
}
I am trying to run a program that will repeatedly read a letter from the user, with the most being entered as 12. If the user enters a sentinel value that they input, the loop should terminate. However, as soon as the first character is read in the loop, it terminates.
Also, the program will place the same word in the reverse order in another array, then check them to see if the first array (read forward), is the same as the other array (read backward). If it is, it displays that the word is a palindrome.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
int charCount, counter, i, temp, check,check2;
char letter[12], letter2[12];
charCount = 0;
counter = 10;
check = 0;
i = 1;
check2 = 0;
printf("Enter your sentinel value.:");
scanf_s(" %c", &letter[check2]);
while ((i<13) && (letter[i] != letter[check2]))
{
printf("Enter individual letters in word (in order).:");
scanf_s(" %c", &letter[i]);
charCount++;
if (letter[i] == letter[check2])
{
break;
}
i++;
}
printf("Letters entered:%i\n", charCount);
for (i = 0; i < charCount; i++)
{
letter2[i] = letter[i];
}
for (i = 0; i <= (charCount / 2); i++)
{
temp = letter2[counter];
letter2[counter] = letter2[i];
letter2[i] = temp;
counter--;
}
for (i = 0; i <= charCount; i++)
{
if (letter[i] = letter2[i])
{
check++;
}
}
if (check = charCount)
{
printf("Word is a palindrome.\n");
}
system("PAUSE");
return 0;
}
the letter[1] value will be unassigned when the while loop enters for the first time right ? I think you can take that condition out of the while loop since you are considering it in the if statement inside the while loop