I'm new in C and I couldnt find the answer to my question in the forum.
The point is, I need to get a value of deck cards from the user. So it can spread from 2 to 10 and also be 'J', 'Q', 'K' or 'A'. That means it can be a integer or a character.
I'm trying to put it in an integer variable called "_val1". This work for any number from 0 to 10. I expected that if I typed a letter, _val1 would get the ASCII value of that character (wich I could use later for my pourposes). But instead _val1 geta value '0' and the letter is automatically passed to my next variable call (wich is _naipe1).
How can I solve that?
That means, how cam I use scanf to get either a integer value or the ASCII value of a character?
short int _val1, _val2;
char _naipe1, _naipe2;
printf("Qual a 1ª carta?\n Valor:");
scanf(" %hd", &_val1);
printf("Valor 1 = %hd \n", _val1 );
printf(" Naipe:");
scanf(" %c", &_naipe1);
well, if I were you I'd try to simplify the problem:
get the ASCII value of the card representation from '2' to '9' and 'J','Q','K','A' ; there you can simply use a scanf("%c") or even better a getchar() operation.
then either you keep using the ASCII representation of your cards throughout your algorithm, or you can translate it using a mapping function such as:
int map(char card) {
switch (card) {
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return card-'0';
case 'A':
return 1;
case 'J':
return 10;
case 'Q':
return 11;
case 'K':
return 12;
}
}
First, there are 52 cards to a typical poker deck, These are split into 4 suits: hearts, diamonds, spades and clubs. This kind of suggests that user input will be something like: 10s, Ad, 3c, etc (meaning 10 of spades, Ace of diamonds and 3 of clubs) So, not only must you determine the value of the individual card, you also must determine the suit.
This will not solve all of those requirements, but it will at least answer your most direct question, how to read an int or a char using scanf().
This will demonstrate that:
#include <stdio.h>
int main(int argc, char** argv)
{
int aNumber;
char aChar;
printf("\nEnter a number:");
scanf("%d", &aNumber);
printf("\nEnter a character:");
scanf("%c", &aChar);
printf("\nThe number entered is %d\n", aNumber);
printf("\nThe character entered is %c\n", aChar);
return 0;
}
You can also simply have all the values in a string such as
char cards[]={"Ad Js 10c 2c Qh"};
Then parse it using strtok(), then test each token for its ascii content, using functions like isdigit() or isalpha()
Note: you will have to map each card to a value to keep them straight, something like this abbreviated enum may work:
enum {
AD = 1, //start enum values at 1 for the diamonds suit
2D,
3D,
...//fill in rest of cards here
JC,
QC,
KC, // last card == 52, with the clubs suit
};
The reason your output from _val1 is 0 when entering a letter lies in the fact that you've declared _val1 as an short int. You should be using a char. Then you can assign and compare their ascii values.
char card;
int value;
scanf("%c", card);
if(card < 58 && card > 49)
value = card - 48;
else {
switch(card) {
case 'a': value = 1;
case '0': value = 10;
case 'j': value = 11;
case 'q': value = 12;
case 'k': value = 13;
default: printf("Must enter 0-9 (0 for 10 card), or a, j, q, k\n");
}
}
To read in "A", "2", "3", ... "10", "J",... "K", use fgetc() and strchr().
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
short GetCardRank(void) {
static const char rank[] = "A234567891JQK";
short val = -1;
int ch = fgetc(stdin);
while (isspace(ch)) ch = fgetc(stdin); // Skip leading white-space
char *p = strchr(rank, toupper(ch)); // Use toupper() to make case insensitive
if (ch != EOF && p != NULL && *p != '\0') {
short val = (short) (p - rank + 1);
if (val != 10) return val;
ch = fgetc(stdin);
if (ch == '0') return val;
val = 1; // Allow a lone '1' to act like an 'A'
}
ungetc(ch, stdin); // Put back unused char for next IO function
return val;
}
I'm trying to put it in an integer variable called "_val1". This work for any number from 0 to 10. I expected that if I typed a letter, _val1 would get the ASCII value of that character (wich I could use later for my pourposes). But instead _val1 geta value '0' and the letter is automatically passed to my next variable call (wich is _naipe1)
The problem is that the %d conversion specifier only recognizes strings of decimal digits (with an optional leading + or -) and will stop reading at the first non-digit character; if you type in something other than a digit, then the input operation will fail and that character will be left in the input stream.
Your best bet is to read your input as text, then convert it to a numerical value manually, something like the following:
#include <ctype.h>
#include <stdlib.h>
/**
* Reads a card's face value (2-10,J,Q,K,A) from standard input
* Returns 0 on error
*/
short get_card_value( void )
{
char buf[4]; // large enough to hold a 2-digit string plus newline plus 0 terminator
short val = 0;
if ( fgets( buf, sizeof buf, stdin ) != NULL )
{
char *chk;
short tmp = (short) strtol( buf, &chk, 0 );
if ( isspace( *chk ) || *chk == 0 )
{
if ( tmp >= 2 && tmp <= 10 )
val = tmp;
}
else
{
switch( tolower( *chk ) )
{
case 'j': val = 11; break;
case 'q': val = 12; break;
case 'k': val = 13; break;
case 'a': val = 11; break;
default: break;
}
}
}
// else read error
return val;
}
You'd call this as
val1 = get_card_value();
if ( val1 == 0 )
// error on input
This code doesn't do any length checking on input, so if you enter a card value of 1234567890, that won't be handled gracefully.
Don't use leading underscores in your variable names; names with leading underscores are reserved for the implementation.
Related
I'm trying to write a program that takes Roman numerals as input and then converts them to decimal values. The user has to first declare how many Roman numerals they are going to input (either one or two).
I am using a for loop that repeats as many times as the number of Roman numerals. It either shouldn't loop if the there is only one numeral or if there are two it should loop twice because we need to take one letter as input at a time.
The issue I was having is that the scanf statement that is inside the for loop, keeps preventing the programme from looping. As soon as I removed the scanf and statically assigned the value then it worked perfectly fine. Then while trying to fix the issue I tried to print out the value scanf is returning by assigning it to a new variable, like char snf = scanf("%s", &numeral); and for some reason it started working exactly I wanted it to work. I have absolutely no idea why it is working now and why it was preventing the loop from looping before. Can anyone explain to me what's going on?
// A program to convert Roman Numerals to Decimals system.
#include <stdio.h>
int convert_numerals(char numeral){
switch(numeral){
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default :
printf("\nError! You did not enter a valid numeral\n");
return 0;}}
int main(){
int Decimal_Val = 0; //Initializing the variable with 0 to avoid issues at check.
int Numeral_Count;
printf("How many characters does your Roman numerals have? 1 or 2\n");
scanf("%d",&Numeral_Count);
for (int i = 1; i < 1+Numeral_Count; ++i)
{
char numeral = 'O';
int converted_val;
printf("\n\nEnter numeral %d : ",i);
scanf("%s", &numeral); // The problematic line.
converted_val = convert_numerals(numeral);
if (Decimal_Val != 0)
{
if (Decimal_Val < converted_val)
{
Decimal_Val = converted_val - Decimal_Val;
}else{
Decimal_Val += converted_val;
}
}else{
Decimal_Val = converted_val;
}
}
printf("\nThe Roman numerals you entered are equal to %d in Decimals\n", Decimal_Val);
return 0;
}
Scanf can be a problematic function, especially with characters. Instead, try using fgets to read a line, then use the first character. If we break this out into a separate function. (Breaking problems down is crucial to solving complex problems in any programming language.)
char get_roman_numeral(const char *prompt, const char * error_msg) {
while (1) {
printf("%s: ", prompt);
char input[20] = {};
fgets(input, 19, stdin);
input[strcspn(input, "\n")] = '\0';
if (strlen(input) > 0) {
switch (input[0]) {
case 'i': case 'I':
case 'v': case 'V':
case 'x': case 'X':
case 'l': case 'L':
case 'c': case 'C':
case 'd': case 'D':
case 'm': case 'M':
return input[0];
default:
printf("%s\n", error_msg);
}
}
else {
printf("%s\n", error_msg);
}
}
}
Picking this apart, we loop indefinitely. Each time we print the prompt we provide, then read a line from stdin into the char buffer input which can hold 20 characters (one of them has to be the null terminating character).
input[strcspn(input, "\n")] = '\0';
This is going to find the first newline character in the input string and set it to '\0'. This effectively removes the newline character than fgets will include in the input string.
If the input string is then longer than 0 characters, we'll evaluate the first character. If it's a roman numeral, we return it. The function is done!
If it's either not a roman numeral, or the string is zero characters in length, we'll print the error message, and the loop starts over.
Hopefully looking at getting your input this way, without the problematic scanf will help you solve the bigger problem.
just decide to stop working for no apparent reason.
Below fails as "%s" attmeps to form a string and numeral is only big enoguh for the stirng "".
//char numeral = 'O';
//scanf("%s", &numeral); // The problematic line.
char numeral[100];
if (scanf("%99s", &numeral) == 1) {
// Success, continue and use `numeral`
converted_val = convert_numerals(numeral); will need to change too as that only handles 1 char.
I have a homework problem. It requires me to convert a word into uppercase and several characters have to be converted to decimal for example :
"Hello my NamE is FeLix" --> "H3LL0 MY N4M3 15 F3L1X". So, these characters had to be converted :
I = 1
S = 5
E = 3
O = 0
A = 4
etc.
How to convert it? I already tried to convert it to capslock but i cannot convert it into decimal.
I already tried to convert the words into uppercase, but have no idea how to convert the character into numbers.
int main()
{
char sentence[200];
int sentencelength = strlen(sentence);
// Ambil data user
scanf("%s",&sentence); getchar();
// Cek satu persatu pake for
for (int i= 1; i <= sentencelength; i++) {
if(sentence[i] >= 'a' && sentence[i] <= 'z') {
char uppercase = sentence[i] + 'A' - 'a';
printf("%c",uppercase);
}
}
getchar();
return 0;
}
There is no error, but I just have no idea how to convert it.
You can use switch as below.
switch(uppercase ) {
case 'I':
uppercase = '1';
break;
case 'S':
uppercase = '5';
break;
case 'E':
uppercase = '3';
break;
…
}
C arrays start at index 0, not 1, so change the for loop bounds to:
for (int i = 0; i < sentencelength; i++) {
You can use toupper (declared by #include <ctype.h>) to convert a character from lowercase to uppercase, leaving non-alphabetic characters alone. It is only defined for values representable by an unsigned char or for the value EOF.
char l33t = sentence[i];
if (l33t == (unsigned char)l33t)
l33t = toupper(l33t);
You can use a switch statement to replace certain uppercase letters with digits:
switch (l33t) {
case 'I':
l33t = '1';
break;
case 'S':
l33t = '5';
break;
case 'E':
l33t = '3';
break;
case 'O':
l33t = '0';
break;
case 'A':
l33t = '4';
break;
}
Rather than using scanf to read a whole word of input into a buffer, an alternative is to read the input a character at a time. Here is an example program that behaves as a filter:
#include <stdio.h>
#include <ctype.h>
static int convert(int ch)
{
if (ch == (unsigned char)ch)
ch = toupper(ch);
switch (ch) {
case 'I': ch = '1'; break;
case 'S': ch = '5'; break;
case 'E': ch = '3'; break;
case 'O': ch = '0'; break;
case 'A': ch = '4'; break;
}
return ch;
}
int main(void)
{
int ch;
while ((ch = getchar()) != EOF) {
ch = convert(ch);
putchar(ch);
}
return 0;
}
The above will convert the whole input until it sees end-of-file. To terminate after a single line, just add a check for a newline character to break out of the while loop.
create an array of characters: [4BCD3F....Z]
and an array of sources: [abcd...z]
run on your string, replace each character found in index I with the same character in the first array, if it's not found return the character as is.
crude, simple, works
Also, if someone complain on the calculation complexity, since you have fixed number of letters in the arrays A to Z , the complexity is O(N*M) when M is const, hence O(N) anyway
I write the following code to convert roman numbers to decimal numbers using C language but it is not giving the correct answers. I have done dry run also. please help.
#include <stdio.h>
int main()
{
char ch;
int num, newnum=0, result=0;
printf("Enter number:");
scanf("%s", &ch);
while (ch != 'n') {
switch (ch) {
case 'i': num = 1; break;
case 'v': num = 5; break;
case 'x': num = 10; break;
case 'l': num = 50; break;
case 'c': num = 100; break;
case 'd': num = 500; break;
case 'm': num = 1000; break;
}
if (newnum > num) {
result = result - num;
newnum = num;
} else {
result = result + num;
newnum = num;
}
printf("Enter number:");
scanf("%s", &ch);
}
printf("%d", result);
}
main()
should be written
int main( void )
This is not just a stylistic nit - as of C99, implicit typing is no longer allowed.
scanf("%s", &ch);
is not what you want here - the s conversion specifier expects ch to point to the first element of an array of char, not a single char object. It tells scanf to read a sequence of non-whitespace characters and store them to a buffer, and it will write the zero terminator to the end of that buffer (i.e., to store a one-character string, you need a 2-element array of char). As written, scanf will write to both ch and the byte immediately following it in memory, which may or may not have an effect elsewhere.
To read a single character from standard input, either use
scanf( " %c", &ch ); // note leading blank in format string; this tells scanf
// to skip over any leading whitespace characters
or
int ch;
...
ch = getchar(); // getchar returns int, not char
You might want to walk through your conversion algorithm on paper a few times. What happens when you enter i followed by v?
I have declared an array char Buffer[100]="01 05 01 4A 63 41"; now the array looks like this
Buffer[0]='0'
Buffer[1]='1'
Buffer[2]=' '
Buffer[3]='0'
Buffer[4]='5'
i just want to convert these value to int `eg.:
Buffer[0]='0', Buffer[1]='1' to 0x01 (1)
Buffer[0]='0', Buffer[1]='5' to 0x05 (5)
... etc.
atoi()cannot be used since it converts all the Buffer value as integer.
How to convert a particular space delimited value sub-string to an integer?
My first solution works only for integers, and the following one works also for hexadecimal numbers. I wrote down the function which converts string representation of a hexadec. number into a decimal number. Then, as suggested by Jochim Pileborg, I used strtok to parse the given Buffer array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int hexToInt(char *tok)
{
int i,out=0, tens=1, digit;
for(i=strlen(tok)-1; i>=0; i--)
{
switch(tok[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': digit=tok[i]-'0';
break;
case 'A': digit=10; break;
case 'B': digit=11; break;
case 'C': digit=12; break;
case 'D': digit=13; break;
case 'E': digit=14; break;
case 'F': digit=15; break;
}
out+=digit*tens;
tens*=16;
}
// printf("hex:%s int:%d ", tok, out);
return out;
}
int main()
{
char Buffer[100]="01 2A 10 15 20 25";
int intarr[100],current=0;
char *tok=malloc(20*sizeof(char));
tok=strtok(Buffer," ");
while(tok!=NULL)
{
intarr[current]=hexToInt(tok);
current++;
tok=strtok(NULL," ");
}
printf("\n");
}
You can treat Buffer as a string (which it is), and use e.g. strtok to "tokenize" the numbers on space boundary. Then use strtol to convert each "token" to a number.
But do note that strtok modifies the string, so if you don't want that you have to make a copy of the original Buffer and work on that copy.
Also note that as the numbers seems to be hexadecimal you can't use atoi because that function only parses decimal numbers. You have to use strtol which can handle any base from 2 to 36.
Consider this:
#include <stdio.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
const char* h = &Buffer[0] ;
int i ;
while( *h != 0 )
{
if( sscanf( h, "%2x", &i ) == 1 )
{
printf( "0x%02X (%d)\n", i, i ) ;
}
h += 3 ;
}
return 0;
}
The output from which is:
0x01 (1)
0x05 (5)
0x01 (1)
0x4A (74)
0x63 (99)
0x41 (65)
I have assumed that all the values are hexadecimal, all two digits, and all separated by a single space (or rather a single non-hex-difgit character), and that the array is nul terminated. If either of these conditions are not true, the code will need modification. For example if the values may be variable length, then the format specifiers need changing, and, you should increment h until a space or nul is found, and if a space is found, increment once more.
You could write similar code using strtol() instead of sscanf() for conversion, but atoi() is specific to decimal strings, so could not be used.
If you are uncomfortable with the pointer arithmetic, then by array indexing the equivalent is:
#include <stdio.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
int c = 0 ;
int i ;
while( *h != 0 )
{
if( sscanf( &Buffer[c], "%2x", &i ) == 1 )
{
printf( "0x%02X (%d)\n", i, i ) ;
}
c += 3 ;
}
return 0;
}
and the strtol() version if you prefer:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
const char* h = &Buffer[0] ;
while( *h != 0 )
{
int i = strtol( h, 0, 16 ) ;
printf( "0x%02X (%d)\n", i, i ) ;
h += 3 ;
}
return 0;
}
You can use sscanf for this, e.g.:
int intarr[6];
sscanf(Buffer,"%d %d %d %d %d %d",&intarr[0],&intarr[1],&intarr[2],&intarr[3],&intarr[4],&intarr[5]);
You can cast Buffer[i] to int.
Then check its value, which will be in ASCII.
48->0
.
.
57->9
You can even compare the char to its ASCII value without casting
int CharToDigit(char c)
{
if(c>=48 && c<=57) // or as suggested if(c>='0' && c <='9')
return (int)c - 48; // subtract the ascii of 0
return -1; // not digit
}
For digits from A to F you'll have to subtract 55 from uppercase letters (65-10, 65 is ascii of A)
Then loop through the chars in Buffer sending them to the function: CharToDigit(Buffer[i]) and check the returned int.
I am new a C. I would like to get help to finish my function.
The mission is:
Write a function that accepts a string maximum length of 256 characters containing characters from 'a' to 'z'.
The function to print the number of occurrences of each character.
For example: input abba output will be:
a = 2 b = 2 c = 0 d = 0 .... z = 0
Do not use if during any function.
I would like to get your help to finish this program please.
This is my code
#include "stdlib.h"
#include "conio.h"
#include "stdio.h"
#include "string.h"
#define size 256
void repeat(char *str);
void main()
{
char str[size];
printf("Please enter a string:\n");
flushall;
gets(str);
repeat(str);
system("pause");
return ;
}
void repeat(char *str)
{
char temp=strlen(str);
int i, count=0;
do
{
for (i=0; i<temp ; i++)
{
count += (*str == str[temp-i]);
}
printf("Char %c appears %d times\n ",*str,count);
count=0;
}
while(*(str++));
}
Please enter a string:
abbba
Char a appears 1 times
Char b appears 2 times
Char b appears 1 times
Char b appears 0 times
Char a appears 0 times
Char appears 0 times
Press any key to continue . . .
this is the output!
I would like to do it in the same building i did.
and should be like
Char a appears 2 times
Chars b appears 3 times
You make a stipulation about not using if. This satisfies that restriction.
#include <stdio.h>
int main(void) {
int i, c;
int counts[256] = { 0 };
const char lower[] = "abcdefghijklmnopqrstuvwxyz";
while ((c = getchar()) != EOF) {
counts[c] += 1;
}
for (i = 0; lower[i]; ++i) {
c = lower[i];
printf("Char %c appears %d times.\n", c, counts[c]);
}
return 0;
}
The problem with your attempt is that you do not track any state to remember which characters you have already printed information about. It also fails to include the character under consideration as part of the count. It also makes multiple passes over the string to collect count information about each character, but that doesn't affect correctness, just performance. If you can somehow remember which character you have already printed out information for, so that you don't do it again when the same character appears later in the string, your method should print out the counts for the characters that appear. Afterwards, you would need to print out zero counts for the characters that did not appear at all. If the outputs need to be in alphabetical order, then you need to make sure you take care of that as well.
One way to track the information properly and to allow your output to be printed in alphabetical order is to maintain counts for each character in an array. After making a pass over the string and incrementing the count associated with each found character, you can iterate over the count array, and print out the counts.
The following program is for zubergu:
#include <stdio.h>
#include <string.h>
int main (void) {
int i, c;
int counts[26] = { 0 };
const char lower[] = "abcdefghijklmnopqrstuvwxyz";
while ((c = getchar()) != EOF) {
switch (c) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z':
counts[strchr(lower, c) - lower] += 1;
break;
default:
break;
}
}
for (i = 0; lower[i]; ++i) {
printf("Char %c appears %d times.\n", lower[i], counts[i]);
}
return 0;
}
It might be one of the ugliest solutions, but also the simplest:
while(*str!='\0')
{
switch(tolower(*str))
{
case 'a': a_count++;break;
case 'b': b_count++;break;
.
.
.
}
str++;
}
It checks if str points to valid letter, then turns it to lower, so it's not case sensitive('A' will be same as 'a' character). No 'if' used and will work with every length char array terminated with '\0' char.
EDIT I have edited the program to follow the requirements of #SagiBinder.
(In my old version, I used an if sentence that checked if the character is in the set 'a'...'z').
The type of temp must be "bigger", that is, something different to char.
Try int, instead.
The algorithm would be this (some details of your program are not repeated here):
int temp = strlen(str);
int i, j;
unsigned char c;
int ch[UCHAR_MAX]; // The macro CHAR_MAX needs the header <limits.h>
for (i = 1; i <= UCHAR_MAX; i++)
ch[i] = 0;
for (j=0; j<temp ; j++) {
c = (unsigned char)(str[j]);
ch[c]++;
}
for (c = 'a'; c <= 'z'; c++)
printf("%c == %d\n", c, ch[c]);
The variable temp holds the length of the string str.
The macro UCHAR_MAX (existing in the header <limits.h>, that you have to #include at the beginning of the program). It is the max. value that holds in a unsigned char.
The array ch[] contains a component for each possible value in the range of the type unsigned char. The intent is that, for some character c, the element ch[c] is the amount of times that c is in str.
I have used unsigned char in order to ensures that the index c of the array ch[] when writting ch[c] is a non-negative integer value, because an array cannot have negative indexes.
The 2nd for goes through the string str. In the step number j, the j-th character of the string str is taken.
This character is a value of type char.
Since one cannot be sure that char have not negative values, I have converted it to (unsigned char) with an explicit cast.
This value is held in the variable c.
The value of c has the (unsigned char version of the) j-th character in str,
so we are going to count it.
How?
Well, we access the array of counters: ch[] with index c, and increment its value in 1:
ch[c]++;
After the for is finished, we have in the array ch[] the information we want.
Finally, we check for the characters from 'a' to 'z'.
(For this, we have supposed that the character encodings in our system follow the convention that the letters have contiguous values).
The 3rd for goes from 'a' to 'z', and the values of the letter (the variable c that controls the for) and the counting of this letter, that is, ch[c].
Moreover: to show the count of any character, you need a re-cast to char, in this way:
printf("%c: %d\n", (char)c, ch[c]);
But this is not necessary with the letters 'a' to 'z', because they belong to the basic execution character set which means that their values are non-negative and equal to their unsigned char counterparts. So, in this case, it is enough to write:
printf("%c: %d\n", c, ch[c]);
EDIT 2: I will use the idea in the answer of #jxh to improve my code.
Since it cannot be guaranted that the encodings of letters 'a' to 'z' are in contiguous order, we can use a string holding the letters:
char letters[] = "abcdefghijklmnopqrstuvwxyz";
The "last" element is, by C convention, a \0 character held after the element 'z'.
Now, we can show the letter counting by changing the 3rd `for` in this way:
for (i = 0; letter[i] != '\0'; i++)
printf("%c == %d\n", letter[i], ch[letter[i]]);
This is equivalent to write:
for (i = 0; letter[i] != '\0'; i++) {
c = letter[i];
printf("%c == %d\n", c, ch[c]);
}
Optimized solution. complexity O(N), N - Input String length.
your void repeat function will be like this,
void repeat(char *str)
{
int temp=strlen(str);// use int here
int i, count=0;
int charCount[26] = {0};
#if 0
//your logic, traverses the string (n*n) time, n - input string length.
do
{
for (i=0; i<temp ; i++)
{
count += (*str == str[temp-i]);
}
printf("Char %c appears %d times\n ",*str,count);
count=0;
}
while(*(str++));
#endif
#if 1
// This logic traverses string once only. n time, n - input string length.
for (i=0; i<temp ; i++)
{
charCount[str[i]%'a']++;
}
for (i=0; i<26 ; i++)
{
printf("%c appears : %d times \n", 'a'+i, charCount[i]);
}
#endif
}
[EDIT]
Here
charCount[str[i]%'a']++; // 'a' is used a its ASCII Value.
You can use it as
charCount[str[i]%97]++;
If you wan to count lower case letter and upper case letter both.
use it like this
if(str[i] >= 'a' && str[i] <= 'z'){
iMap = str[i]%97; // 97 is ASCII Value of 'a'
charCount[iMap]++;
}else if(str[i] >= 'A' && str[i] <= 'Z'){
iMap = str[i]%65; // 65 is ASCII Value of 'A'
charCount[iMap]++;
}
//iMpa is a integer (int iMap;), used for better undersanding.
i = 0;
while (s[i] !=0)
if (( s[i] >= 'a' && s[i] <= 'z') || (s[i] <= 'A' && s[i] >= 'Z'))
{
letters++;
i++;
}
else
if (( s[i] >= '!' && s[i] <= ')'))
{
other++;
}
else
if (( s[i] >= '0' && s[i] <= '9'))
{
numbers++;
}
total = letters + numbers + other;