Bug Histogram Display in C - c

i want to do a histogram vertical display of my "election".
My code work just it seems to display wrongly the vote for the 10,11,12,13 value because i think there is 2 numbers ...
thank you for your time ;)
int main() {
char character ;
int TAB[12] = {0} ;
int vote = 0;
int I;
printf("Please enter a character:\n"); //character for the display
scanf(" %c", &character); // character we want to display in the histogram
printf("Please enter votes\n");
while(1) {
scanf("%d", &vote);
if (vote == -1) {
break;
}
TAB[vote-1]++; //save the vote into the array
}
printf("Histogram :\n");
/* Search for the maximum value */
int MAX=0;
for (I=0; I<12; I++)
{
if(TAB[I]>TAB[MAX]) MAX=I;
}
int maximum = TAB[MAX]; // maximum value
while (maximum > 0) {
for (I = 0; I < 12; I++) {
if (TAB[I] == maximum) {
printf("%c ",character);
TAB[I] = (TAB[I] - 1) ;
}
else {
printf(" ");
}
}
maximum= maximum - 1;
printf("\n");
}
for (I = 0; I < 13; I++) {
printf("%d ",I+1); // display the number of each candidat
}
printf("\n"); // go to the line
return 0;
}

You shouldn't use magic number 12, use like #define VOTE_MAX 13
For the range of vote, use if (vote <= 0 || vote > VOTE_MAX)
Format output, like printf("%2c ", character);
The line for (I = 0; I < 13; I++) { should be for (I = 0; I < 12; I++) {
The following code could work:
#include <stdio.h>
#define VOTE_MAX 13
int main() {
char character;
int TAB[VOTE_MAX] = {0};
int vote = 0;
printf("Please enter a character:\n"); // character for the display
scanf(" %c", &character); // character we want to display in the histogram
printf("Please enter votes\n");
while (1) {
scanf("%d", &vote);
if (vote <= 0 || vote > VOTE_MAX) {
break;
}
TAB[vote - 1]++; // save the vote into the array
}
printf("Histogram :\n");
/* Search for the maximum value */
int MAX = 0;
for (int i = 0; i < VOTE_MAX; ++i) {
if (TAB[i] > TAB[MAX]) MAX = i;
}
int maximum = TAB[MAX]; // maximum value
while (maximum > 0) {
for (int i = 0; i < VOTE_MAX; ++i) {
if (TAB[i] == maximum) {
printf("%2c ", character);
--TAB[i];
} else {
printf("%2c ", ' ');
}
}
--maximum;
printf("\n");
}
for (int i = 0; i < VOTE_MAX; ++i) {
printf("%2d ", i + 1); // display the number of each candidat
}
printf("\n"); // go to the line
return 0;
}

You need to add an extra space for the cases where I is 10 or higher.
Like:
for (I = 0; I < 12; I++) {
if (TAB[I] == maximum) {
printf("%c ",character);
TAB[I] = (TAB[I] - 1) ;
}
else {
printf(" ");
}
if (I >= 9) printf(" "); // Add extra space for 10, 11 and 12
}
BTW: your input method should be improved. Currently the user can enter values that will make your write outside the array. At least do something like:
while(1) {
if (scanf("%d", &vote) != 1) break; // Catch illegal input
if (vote <= 0 || vote >= 13) { // Only allow vote to be 1, 2, …, 10, 11, 12
break;
}
TAB[vote-1]++; //save the vote into the array
}

Related

C program to insert elements into an array until user inputs a 0 or less number

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])

one of the output is showing (null) result on a simple struct program (no Array of Struct)

I've created a simple program for displaying college student data and counting the accumulation of score into a grade (A,B,C,D,E) and using struct (Im prohibited to create with Array of Struct), so the problem is one of the output which is "Grade" is giving (null) result when printed with %s and completely blank result when printed with %c. The type of the "Grade" data is char by the way. Here is the complete code.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <ctype.h>
struct student
{
char nim[11];
char name[100];
char subjectCode[5];
int sks;
char grade;
}studentScore[100];
bool cekKarakter(char input[])
{
for(int x = 0; x < strlen(input); x++)
{
if(isdigit(input[x]))
return false;
}
return true;
}
bool cekNumeric(char input[])
{
for(int x = 0; x < strlen(input); x++)
{
if(input[x] >= 48 && input[x] <= 57)
return false;
}
return true;
}
int main()
{
int n;
printf("Input number of Student Data: ");
scanf("%d", &n);
fflush(stdin);
printf("\n\n");
for(int i = 1; i <= n; i++)
{
do
{
printf("NIM [Hanya numerik][10 Digit]: ");
gets(studentScore[i].nim);
fflush(stdin);
}
while(strlen(studentScore[i].nim) != 10 ||
cekNumeric(studentScore[i].nim));
printf("\n");
do
{
printf("Name [Hanya karakter]: ");
gets(studentScore[i].name);
fflush(stdin);
}
while(strlen(studentScore[i].name) < 5 || strlen(studentScore[i].name) >
30 || cekKarakter(studentScore[i].name) == false);
printf("\n");
do
{
printf("Subject Code [Must 5 length]: ");
gets(studentScore[i].subjectCode);
fflush(stdin);
}
while(strlen(studentScore[i].subjectCode) != 5);
printf("\n");
do
{
printf("SKS [Min 2|Max 8]: ");
scanf("%d", &studentScore[i].sks);
fflush(stdin);
}
while(studentScore[i].sks < 2 || studentScore[i].sks > 8);
printf("\n");
int score[5];
int WeightGrade = 0;
printf("Input 5 College Subject Score:\n\n");
for(int z = 0; z < 5; z++)
{
do
{
printf("Input Score[%d][Must be between 0 and 100]: ", z + 1);
scanf("%d", &score[z]);
}
while(score[z] < 0 || score[z] > 100);
WeightGrade += score[z];
}
if(WeightGrade / 25 == 4)
{
studentScore[i].grade = 'A';
}
else if(WeightGrade / 25 >= 3 && WeightGrade / 25 < 4)
{
studentScore[i].grade = 'B';
}
else if(WeightGrade / 25 >= 2 && WeightGrade / 25 < 3)
{
studentScore[i].grade = 'C';
}
else if(WeightGrade / 25 >= 1 && WeightGrade / 25 < 2)
{
studentScore[i].grade = 'D';
}
else if(WeightGrade / 25 == 0)
{
studentScore[i].grade = 'E';
}
}
printf("\nStudent Data\n");
for(int i = 1; i <= n; i++)
{
printf("NIM: %s\nName: %s\nSubject Code: %s\nSKS: %d\nGrade: %s\n",
studentScore[i].nim,
studentScore[i].name,
studentScore[i].subjectCode,
studentScore[i].sks,
studentScore[i].grade);
}
getchar();
return 0;
}
This is the image of the program when it's running
(null) output result using %s as printed
In your code, WeightGrade is actually the sum of all grades, so for your example - WeightGrade=370.
370/25 doesn't fall within any of the options, so studentScore[i].grade doesn't get any value. To prevents this cases, always input an else clause that shows an error
Since you have 5 values, you should divide by 5*25=125, as in WeightGrade/125
Also for printf, you shouldn't use %s on char value, you should use %c

While Loop not Executing in C

I am unable to get this program to print out the lines of symbols with a tab. I included a picture of how it should be printing. Currently it's working except that there is no indentation. Any help at all would be greatly appreciated.
The idea is to display even numbered lines with indents (‘\t’) and the odd ones without indent:
Example of correct output
#include <stdio.h>
int main(void) {
int num_lines;
printf("Enter a number of lines, greater than or equal to 7, to print : ");
scanf("%d", &num_lines);
if (num_lines < 7) {
while ( num_lines < 7 ) {
printf("Enter the number of lines to print\nMust be greater than or equal to 7 : ");
scanf("%d", &num_lines);
}
}
char symbol;
printf("Choose a symbol/character to be displayed */&/+/0/x : ");
scanf(" %c", &symbol);
int num_symbols;
printf("Enter the number of symbols to print per line : ");
scanf("%d", &num_symbols);
if (num_symbols < 7 || num_symbols > 27) {
num_symbols = 19;
}
while (num_lines > 0) {
int n = num_symbols;
int nl = 1;
int nll = nl / 2;
while (nl <= num_lines) {
if ( (nl % 2) == 0) {
while (nll > 0) {
printf("\t");
--nll;
}
while (n > 0) {
printf("%c", symbol);
--n;
}
}
else {
while (n > 0) {
printf("%c", symbol);
--n;
}
}
++nl;
}
printf("\n");
--num_lines;
}
return;
}
In your loop there are problems in the way you declare your variables and put your conditions.
Try to think step by step:
1. Am I on on a pair or impair line?
2. If yes I put \t
3. Print x times my number
4. Do the same until you've done enough lines
if (num_symbols < 7 || num_symbols > 27) {
}
int which_line = 1;
while (num_lines > 0) {
if (which_line % 2 == 0) { //STEP 1
for (int tmp_line = which_line - 1; tmp_line >= 1 ; tmp_line--) { //STEP2
printf("\t");
}
}
for (int tmp_symbols = num_symbols; tmp_symbols >= 1 ; tmp_symbols--) { //STEP 3
printf("%c", symbol);
}
printf("\n");
which_line++; //STEP 4
--num_lines;
}
You can try this to print your desired pattern :
#include<stdio.h>
int main(void) {
int num_lines,i,j;
printf("Enter a number of lines, greater than or equal to 7, to print : ");
scanf("%d", &num_lines);
while ( num_lines < 7 ) {
printf("Enter the number of lines to print\nMust be greater than or equal to 7 : ");
scanf("%d", &num_lines);
}
char symbol ;
printf("Choose a symbol/character to be displayed */&/+/0/x : ");
scanf(" %c", &symbol);
int num_symbols;
printf("Enter the number of symbols to print per line : ");
scanf("%d", &num_symbols);
if (num_symbols < 7 || num_symbols > 27) {
num_symbols = 19;
}
i = 1;
while (i <= num_lines) {
if(i%2 == 0){
j = i/2;
while(j != 0){
printf("\t");
j--;
}
}
j = 0;
while(j < num_symbols){
printf("%c",symbol);
j++;
}
printf("\n");
i++;
}
return 0;
}
^_^
#include <stdio.h>
int main(void) {
int num_lines;
do{
printf("Enter the number of lines to print\nMust be greater than or equal to 7 : ");
scanf("%d", &num_lines);
}while(num_lines < 7);
char symbol;
printf("Choose a symbol/character to be displayed */&/+/0/x : ");
scanf(" %c", &symbol);
int num_symbols;
printf("Enter the number of symbols to print per line : ");
scanf("%d", &num_symbols);
if (num_symbols < 7 || num_symbols > 27) {
num_symbols = 19;
}
for (int i = 1; i <= num_lines; ++i) {
if (i % 2 == 0) {
for (int m = 0; m < i / 2; ++m) {
printf("\t");
}
}
for (int j = 0; j < num_symbols; ++j) {
printf("%c", symbol);
}
printf("\n");
}
return 0;
}

Detect if the number in the array has been already input (C program)

I am kind of confused. I'd like to make a program where if the number in the array has been already input, then it will detect it and say it was repeated, so the program would tell the user to put another non-repeated integer.
#include <stdio.h>
#define SIZE 5
int main()
{
int array[SIZE];
int i;
int j;
for (i = 0; i < SIZE; i++)
{
printf("[%d] Insert a number: ", i + 1);
scanf("%d", &array[i]);
j = i - 1; // This is the closest that I've gotten guys. But I need to create a loop to make j be -1 until it finds a repeated number in the array.
if (array[i] == array[j])
{
printf("The number is repeated");
i--;
}
if (array[i] > 1000)
{
printf("Sorry, the number you entered cannot be bigger than 1000\n");
i--;
}
if (array[i] < 0)
{
printf("Sorry, the number you entered cannot be less than 0\n");
i--;
}
}
for (i = 0; i < SIZE; i++)
{
printf("The array inside is %d\n", array[i]);
}
return 0;
}
As you can see, I did something similar. I just put j = i - 1 so basically it will tell the program that it was repeated. However, I suppose that I should create a loop that will subtract -1 to j until it finds the repeated value (if there is one). I just not have any idea how to create that loop and make it work.
Thank you very much!
The checks can be done the following way (without testing)
int array[SIZE];
int i;
for (i = 0; i < SIZE; i++)
{
int valid = 1;
int num;
do
{
printf("[%d] Insert a number: ", i + 1);
scanf("%d", &num );
if ( !( valid = !( num > 1000 ) ) )
{
printf("Sorry, the number you entered cannot be bigger than 1000\n");
}
else if ( !( valid = !( num < 0 ) ) )
{
printf("Sorry, the number you entered cannot be less than 0\n");
}
else
{
int j = 0;
while ( j < i && num != array[j] ) j++;
if ( !( valid = j == i ) )
{
printf("The number is repeated");
}
}
} while ( !valid );
array[i] = num;
}
This should work for you:
#include <stdio.h>
#define SIZE 5
int main() {
int array[SIZE];
int numberCount, repeatCount;
for(numberCount = 0; numberCount < SIZE; numberCount++) {
printf("[%d] Insert a number:\n>", numberCount + 1);
scanf("%d", &array[numberCount]);
for(repeatCount = 0; repeatCount < numberCount; repeatCount++) {
if (array[numberCount] == array[repeatCount]) {
printf("\nThe numbe is repeated\n");
numberCount--;
break;
}
}
if (array[numberCount] < 0) {
printf("\nSorry, the number you entered cannot be less than 0\n");
numberCount--;
}
if (array[numberCount] > 1000) {
printf("\nSorry, the number you entered cannot be bigger than 1000\n");
numberCount--;
}
}
printf("\n\n");
for(numberCount = 0; numberCount < SIZE; numberCount++)
printf("The array inside is %d\n", array[numberCount]);
return 0;
}

Replacing elements in an array

I have a problem thats giving me a huge ache.
This piece of code purpose is to fill up an array with integer values and at the same time defend against strings and etc....but it doesn't defend against duplicates, but tried I got to far as replacing the number with a new number for example
Enter 6 integers
1, 2, 2, 3, 4, 5
my code will let me replace that 2 at position 1 with another number. What I want it to do is not to repeat the same number again, for example please replace 2 at position 1. I dont want the user to enter 2 again... and I want to make it to double check the work the array if any repeating numbers exists thank you.
system("clear");
printf("\nEntering Winning Tickets....\n");
nanosleep((struct timespec[]){{1, 0}}, NULL);
system("clear");
char userInput[256];
char c;
int duplicationArray[6] = {-1, -1, -1, -1, -1, -1};
for (i = 0; i < 6; i++)
{
printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
fgets(userInput, 256, stdin);
if ((sscanf(userInput, "%d %c", &winningNumbers[i], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
printf("\nInvalid Input.\n") ;
nanosleep((struct timespec[]){{0, 350000000}}, NULL);
system("clear");
i = i - 1;
}
}
for (i = 0; i < 6 - 1; ++i)
{
min = i;
for (j = i+1; j < 6; ++j)
{
if (winningNumbers[j] < winningNumbers[min])
min = j;
}
temp = winningNumbers[i];
winningNumbers[i] = winningNumbers[min];
winningNumbers[min] = temp;
}
for (i = 0; i < 6; i++)
{
if (winningNumbers[i] == winningNumbers[i+1])
{
duplicationArray[i] = i;
duplicationCounter++;
}
else
{
duplicationCounter--;
}
}
if (duplicationCounter > -6)
{
for (i = 0; i < 6; i++)
{
int j, min, temp;
min = i;
for (j = i+1; j < 6; ++j)
{
if (duplicationArray[j] > duplicationArray[min])
min = j;
}
temp = duplicationArray[i];
duplicationArray[i] = duplicationArray[min];
duplicationArray[min] = temp;
}
for (i = 0; i < 6; i++)
{
if (duplicationArray[i] == -1)
{
zeroCounter++;
}
}
int resize = (6 - zeroCounter)+1;
for (i = 0; i <= resize; i++)
{
if (duplicationArray[i] == -1)
{
i++;
}
else if (duplicationArray[i] != -1)
{
system("clear");
printf("\nDuplicated numbers has been dected in your array. ");
printf("\nPlease replace the number %d at postion %d with another number: ", winningNumbers[duplicationArray[i]], duplicationArray[i]);
fgets(userInput, 256, stdin);
if ((sscanf(userInput, "%d %c", &winningNumbers[duplicationArray[i]], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
printf("\nInvalid Input.\n") ;
nanosleep((struct timespec[]){{0, 350000000}}, NULL);
system("clear");
i = i - 1;
}
}
}
duplicationCounter = 0;
for (i = 0; i < 6; i++)
{
if (winningNumbers[i] == winningNumbers[i+1])
{
duplicationArray[i] = i;
duplicationCounter++;
}
else
{
duplicationCounter--;
}
}
printf("%d, ", duplicationCounter);
}
#include <stdio.h>
#include <stdint.h>
#define DATA_SIZE 6
int main(void){
char userInput[256];
int inputNum, winningNumbers[DATA_SIZE];
uint64_t table = 0;
int i=0;
while(i<DATA_SIZE){
printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
fgets(userInput, sizeof(userInput), stdin);
if(sscanf(userInput, "%d", &inputNum) != 1 || inputNum <= 0 || inputNum >= 50)
continue;
uint64_t bit = 1 << inputNum;
if(table & bit)
continue;
table |= bit;
winningNumbers[i++] = inputNum;
}
for(i=0;i<DATA_SIZE;++i)
printf("%d ", winningNumbers[i]);
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 6
int inputNumberWithRangeCheck(const char *msg, const char *errMsg, int rangeStart, int rangeEnd){
char inputLine[256];
int n;
for(;;){
printf("%s", msg);
fgets(inputLine, sizeof(inputLine), stdin);
if(sscanf(inputLine, "%d", &n) != 1 || n < rangeStart || n > rangeEnd)
fprintf(stderr, "%s", errMsg);
else
return n;
}
}
int inputNumber(void){
return inputNumberWithRangeCheck(
"\nPlease enter the winning ticket number!(#'s must be between 1-49): ",
"Invalid Input.\n",
1,49);
}
int *inputArray(int *array, size_t size){
int i;
for(i=0;i<size;++i){
printf("\nInput for No.%d\n", i+1);
array[i] = inputNumber();
}
return array;
}
int **duplicateCheck(int *array, size_t size){
int **check, count;
int i, j;
check = malloc(size*sizeof(int*));
if(!check){
perror("memory allocate\n");
exit(-1);
}
//There is no need to sort the case of a small amount of data
//(Cost of this loop because about bubble sort)
for(count=i=0;i<size -1;++i){
for(j=i+1;j<size;++j){
if(array[i] == array[j]){
check[count++] = &array[i];
break;
}
}
}
check[count] = NULL;
if(count)
return check;
else {
free(check);
return NULL;
}
}
int main(void){
int winningNumbers[DATA_SIZE];
int **duplication;
int i, j;
inputArray(winningNumbers, DATA_SIZE);
while(NULL!=(duplication = duplicateCheck(winningNumbers, DATA_SIZE))){
for(i=0;i<DATA_SIZE;++i){
if(duplication[i]){
printf("\nyour input numbers : ");
for(j=0;j<DATA_SIZE;++j)
printf("%d ", winningNumbers[j]);
fprintf(stderr, "\nThere is duplicate. Please re-enter.\n");
*duplication[i] = inputNumber();
} else
break;
}
free(duplication);
}
for(i=0;i<DATA_SIZE;++i)
printf("%d ", winningNumbers[i]);
printf("\n");
return 0;
}

Resources