I am quite newbie in c, so I just starting off with some code, experimenting some stuff, right now I am stuck with this problem in C, creating a function that displays the alphabet in lowercase, on a single line, by ascending order, starting from the letter ’a’.
This is where I am stuck:
#include <stdio.h>
int alfabet(unsigned int i) {
if(i <= 122) {
char litera = i;
return litera;
}
return alfabet(i+1);
}
int main() {
int i = 97;
printf(alfabet(i));
return 0;
}
Here, you won't print anything really interesting. In fact, your application will crash because printf() require at least a char * parameter (a string).
Your alfabet() function seems not so bad, but you should print the letter in it :
int alfabet(unsigned int i)
{
if (i > 'z') {
// Here is the stop condition.
// If the value is higher than 122 ('z' character), we stop recursivity)
return;
}
printf("%c ", i);
// Otherwise, let's call this function with another character
return alfabet(i+1);
}
Target simplicity
void alfabet(int c) {
printf("%c", c);
if (c < 'z') alfabet(c+1);
}
called from main as
alfabet('a');
You may add a printf("\n");
the function prints the character given as parameter
you only call recursively the function with the next character to be printed if necessary, i.e. if the current character is below z.
Something like that:
#include <stdio.h>
void alfabet(char i) {
if(i < 'z')
{
alfabet(i+1);
}
printf("%c", i);
}
int main() {
char i = 'a';
alfabet(i);
return 0;
}
to print zyxwvutsrqponmlkjihgfedcba. Or:
#include <stdio.h>
void alfabet(char i) {
printf("%c", i);
if(i < 'z')
{
alfabet(i+1);
}
}
int main() {
char i = 'a';
alfabet(i);
return 0;
}
to print abcdefghijklmnopqrstuvwxyz
As you are new in this language, the basic thing to know is that each and every character on the keyboard has its own ASCII value ranging from 000 to 127 (i.e. total 128).
Now if you want to print a to z in a single line, the ASCII value for 'a' is 97 and that for 'z' is 122.
So, for printing this on screen you need to learn the basic for loop structure.The syntax for basic for loop is as follows :-
for(expr1;expr2;expr3)
{
Body of the loop;
}
Here, expr1 refers to the initial value of the variable, expr2 refers to the exit condition of the loop and expr3 refers to the increment or decrement value.
So, the code to print a to z is as follows :-
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
print_alpha();
getch();
}
void print_alpha()
{
int i;
for(i=97;i<+122;i++)
{
printf("%c",i);
}
}
int main() {
int i = 97;
printf("%c",alfabet(i));
return 0;
}
You Have to provide format specifier in printf (i.e. %c for character, %d for integer) Just check man printf in terminal.
And for printing a to z you can use for loop suggested by #Michel Jord, for printing in one line just put space in place of \n
#include <stdio.h>
void print_alphabets(char i) {
if(i>='a' && i<='z')
{
print_alphabets(i+1);
printf("%c ", i);
}
}
int main() {
char i;
scanf("%c",&i);
print_alphabets (i);
return 0;
}
Related
I'm going to make a palindrome which should ignore spaces and special characters and should convert all uppercase letters in the string to lowercase. I have done everything, but when I run my program, neither of these two functions work. Convert uppercase to lowercase and ignore all non-uppercase letters. Could any of you help me to solve what is the problem?
#include<stdio.h>
#define SIZE 1000
#include <ctype.h>
#include<string.h>
// function that checks if it is a palindrome
int isPalindrome(char inputString[]) {
int l = 0;
int r = strlen(inputString) - 1;
while (r > l)
{
// will check all letters are equal to each other
if (inputString[l++] != inputString[r--]) {
return 0;
}// return 0 if not palindrome
}
// palindrome
return 1;
}
// function that ignores all non - letters
int no_special_characters(char inputString[])
{
char temp[SIZE];
int temp_index = 0;
int abc = 0;
int r = strlen(inputString);
for (int i = 0; i < r; i++)
{
char abc = inputString[i];
if (isalpha(abc) != 0)
{
temp[temp_index++] = abc;
}
}
temp[temp_index] = '\0';
return isPalindrome(temp);
}
// function that converts uppercase letters to lowercase
void to_lower(char inputstring[]) {
int length = strlen(inputstring);
for (int i = 0; i < length; i++)
{
if (isupper(inputstring[i]))
inputstring[i] = tolower(inputstring[i]);
else if (islower(inputstring[i]))
inputstring[i] = toupper(inputstring[i]);
}
return 0;
}
int main(void) {
int try_again = 1;
int end_run = 0;
while (try_again == 1) {
int try_again;
char inputString[SIZE] = "";
printf("Enter a string to check if it is a palindrome!\n");
//Scans the input string.
scanf_s("%s", &inputString, SIZE);
//Sends the string to the isPalindrome function. //If the return value is 1(true), the if statement is executed, otherwise the else statement.
if (isPalindrome(inputString)) {
printf("That is a palindrome!\n");
}
else {
printf("This is not a palindrome!\n");
}
printf("Do you want to try again: 1 for yes 0 for No?");
scanf_s("%d", &try_again);
//Changes the value of running depending on whether you want to continue or not.
if (try_again != 1) {
end_run = 0;
}
}
return 0;
}
1 - Don't use scanf
You shouldn't use scanf to read input from the console, especially in a loop. I'm not an expert in scanf_s in particular, but that whole family of functions can cause weird bugs if you don't know how they work. I recommend you read this article, it explains it better that I can.
2 - Your loop doesn't work
You are defining try_again in function scope and then redefining it in block scope: they are two different variables.
Your code is essentially this:
int main(void) {
int try_again = 1;
while (try_again == 1) {
int try_again;
scanf_s("%d", &try_again);
}
}
Which will run forever, since the while loop is checking the first variable, while you are assigning to the second one. It should look more like this:
int main(void) {
int try_again = 1;
while (try_again == 1) {
// int try_again;
// ^^ Don't refefine - use the one already defined
try_again = some_function_to_read_input();
}
}
3 - to_lower doesn't actually convert to lowercase
It converts uppercase to lowercase and lowercase to uppercase. This means "Aa" becomes "aA", which is not a palindrome even though it should be by your definition.
The function doesn't need to return anything, since it changes the string in place. You can simply call it like this:
int isPalindrome(char inputString[]) {
to_lower(inputString);
// Rest of code
}
4 - You aren't calling no_special_characters
You simply aren't calling it. Either you do it in your main, something like:
// main
if (no_special_characters(inputString)) {
// Rest of code
}
Or you change it to return the modified string and call it from inside isPalindrome:
void no_special_characters(char inputString[]) {
// Remove all special characters, in place
}
int isPalindrome(char inputString[]) {
no_special_characters(inputString);
to_lower(inputString);
// Rest of code
}
I am solving this problem:
Given a string str containing alphanumeric characters, calculate sum
of all numbers present in the string.
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test
cases follow. Each test case contains a string containing alphanumeric characters.
Output:
Print the sum of all numbers present in the string.
Constraints:
1 <= T<= 105
1 <= length of the string <= 105
Example:
Input:
4
1abc23
geeks4geeks
1abc2x30yz67
123abc
Output:
24
4
100
123
I have come up with the following solution:
#include <stdio.h>
#include <string.h>
int main() {
//code
int t,j;
char a[100000];
scanf("%d",&t);
while(t--)
{
int sum=0,rev=0,i=0,l;
scanf("%s",a);
l=strlen(a);
for(i=0;i<l;i++)
{
if (isdigit(a[i])){
while(isdigit(a[i])){
rev = rev *10 + (a[i]-48);
i++;
}
}
sum+=rev;
rev=0;
}
printf("%d\n",sum);
}
return 0;
}
This code is working fine.
BUT if loop termination condition is changed from i < l to a[i]!='\0', then code doesn't work. Why?
I would loop backwards over the string. No nested loops. Just take the 10s exponent as you move left
You have the length of the string, so there should be no reason to check for NUL char yourself
(untested code, but shows the general idea)
#include <math.h>
l=strlen(a);
int exp;
exp = 0;
for(i = l-1; i >= 0; i--)
{
if (isdigit(a[i])) {
rev = a[i]-48; // there are better ways to parse characters to int
rev = (int) pow(10, exp) * rev;
sum += rev; // only add when you see a digit
} else { exp = -1; } // reset back to 10^0 = 1 on next loop
exp++;
}
Other solutions include using regex to split the string on all non digit characters, then loop and sum all numbers
You will have to change the logic in your while loop as well if you wish to change that in your for loop condition because it's quite possible number exists at the end of the string as well, like in one of your inputs 1abc2x30yz67. So, correct code would look like:
Snippet:
for(i=0;a[i]!='\0';i++)
{
if (isdigit(a[i])){
while(a[i]!='\0' && isdigit(a[i])){ // this line needs check as well
rev = rev *10 + (a[i]-48);
i++;
}
}
sum+=rev;
rev=0;
}
On further inspection, you need the condition of i < l anyways in your while loop condition as well.
while(i < l && isdigit(a[i])){
Update #1:
To be more precise, the loop while(isdigit(a[i])){ keeps going till the end of the string. Although it does not cause issues in the loop itself because \0 ain't a digit, but a[i] != '\0' in the for loop condition let's you access something beyond the bounds of length of the string because we move ahead 1 more location because of i++ in the for loop whereas we already reached end of the string inside the inner while loop.
Update #2:
You need an additional check of a[i] == '\0' to decrement i as well.
#include <stdio.h>
#include <string.h>
int main() {
//code
int t,j;
char a[100000];
scanf("%d",&t);
while(t--)
{
int sum=0,rev=0,i=0,l;
scanf("%s",a);
l=strlen(a);
for(i=0;a[i]!='\0';i++)
{
if (isdigit(a[i])){
while(a[i] != '\0' && isdigit(a[i])){ // this line needs check as well
rev = rev *10 + (a[i]-48);
i++;
}
}
if(a[i] == '\0') i--; // to correctly map the last index in the for loop condition
sum+=rev;
rev=0;
}
printf("%d\n",sum);
}
return 0;
}
Update #3:
You can completely avoid the while loop as well as shown below:
#include <stdio.h>
#include <string.h>
int main() {
//code
int t,j;
char a[100005];
scanf("%d",&t);
while(t--)
{
int sum=0,rev=0,i=0,l;
scanf("%s",a);
l=strlen(a);
for(i=0;i<l;i++) {
if (isdigit(a[i])){
rev = rev * 10 + (a[i]-48);
}else{
sum += rev;
rev = 0;
}
}
printf("%d\n",sum + rev); // to also add last rev we captured
}
return 0;
}
Other answers have pointed out the correct loop conditions to ensure proper operation of your program.
If you are allowed to use library functions other than isdigit, I would recommend using strtol with the EndPtr parameter (output parameter that points to the character in the string that caused strtol to stop scanning a number):
char str[] = "1abc23def5678ikl";
int main()
{
char *pStop = str;
int n, accum = 0;
size_t len = strlen(str);
do
{
n = strtol(pStop, &pStop, 10);
pStop++;
if(n)
{
printf("%d\n", n);
accum += n;
}
}
while(pStop < &str[len]);
printf("Total read: %d\n", accum);
return 0;
}
I'm having trouble calling the function more than one time in my C program. The gist of the assignment is to replace the whitespaces in a sentence inputted from the user and replace it with a different character. For some reason, the program will call the same first function multiple times. I tried putting the strlen(x) in a variable inside my function, but I'm not very well versed in the C language, so I decided to leave it out of my code.
#include <string.h>
void display(char x[], char y);
void main(){
//Do not change this function
char a[100];
printf("Enter a sentence\n");
gets(a);
display(a, '*'); //To replace every space by *
display(a, '-'); //To replace every space by -
display(a, '+'); //To replace every space by +
}
void display(char x[], char y){
for(char i = 0; i < strlen(x); i++) {
if(x[i] == ' ') {
x[i] = y;
}
}
printf("%s\n", x);
}
It does not "call the same first function". You change the value of your string inside the function, so after the first run of the function the string does not have spaces. Therefore the second and third call print the string unchanged:
void display(char x[], char y){
for(char i = 0; i < strlen(x); i++) {
if(x[i] == ' ') {
// this happens only upon first call!
x[i] = y;
}
}
printf("%s\n", x);
}
Edit: to fix the issue, for example see the comment Ring Ø added and follow the advice
I am always getting the value of each letter I enter as 1 whereas I should get the values as described in the code. Please help find the error in my code.
#include <stdio.h>
#include <ctype.h>
char c;
char num (char c);
int main () {
int sum;
printf("Enter a word:");
c=0;
while (c=getchar() != '\n') {
c=toupper(c);
sum+=c;
}
printf("Scrabble value : %d",sum);
return(0);
}
char num (char c) {
if (c=='A'||c=='E'||c=='I'||c=='L'||c=='N'||c=='O'||c=='R'||c=='S'||c=='T'||c=='U') c=1;
if (c=='D'||c=='G') c=2;
if (c=='B'||c=='C'||c=='M'||c=='P') c=3;
if (c=='F'||c=='H'||c=='V'||c=='W'||c=='Y') c=4;
if (c=='K') c=5;
if (c=='J'||c=='X') c=8;
if (c=='Q'||c=='Z') c=10;
return(c);
}
In short, this will work for you (call num; fixed getchar call in while; initialized sum to 0; no error handling):
#include <stdio.h>
#include <ctype.h>
char c;
char num (char c);
int main () {
int sum = 0;
printf("Enter a word:");
c=0;
while ((c=getchar()) != '\n') {
c=toupper(c);
sum+=num(c);
}
printf("Scrabble value : %d",sum);
return(0);
}
char num (char c) {
if (c=='A'||c=='E'||c=='I'||c=='L'||c=='N'||c=='O'||c=='R'||c=='S'||c=='T'||c=='U') c=1;
if (c=='D'||c=='G') c=2;
if (c=='B'||c=='C'||c=='M'||c=='P') c=3;
if (c=='F'||c=='H'||c=='V'||c=='W'||c=='Y') c=4;
if (c=='K') c=5;
if (c=='J'||c=='X') c=8;
if (c=='Q'||c=='Z') c=10;
return(c);
}
To get this clean, init sum:
int sum = 0;
The logic of your function for determining the value looks OK (maybe apart from the return value),
but you constantly change the parameter c. This does not actually break anything, but looks somewhat confusing. I recommend to change all c= something to return something;.
To have a default handling, change return(c); to return 0;.
Also you never call your function.
Change
sum+=c;
to
sum+=num(c);
Picking up from (absolutely necessary) comment by Some programmer dude (credits),
The expression c=getchar() != '\n' is, due to operator precedence, equal to c=(getchar() != '\n'). This means the value of c will be either 0 or 1, and nothing else. Also note that getchar returns an int, which is important to check for EOF. Lastly, you need to check for EOF or errors in general.
Others have already answered the question, but just for reference, this is how you write a better look-up function:
int get_val (char c)
{
const int VALUES ['Z' - 'A' + 1] =
{
['A' - 'A'] = 1,
['B' - 'A'] = 3,
['C' - 'A'] = 3,
...
};
return VALUES[c - 'A'];
}
I have a kind of logical assignment here in my class. So my question is when I try to strcpy() a string into another string, There's a (like space) in my new string. I don't know how to delete that, perhaps my mistake. Please help me, thank you.
This program let's you type whatever letters or symbol on your keyboard and try to capture it and count the symbol. Then, return it.
Here's my code in C
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#define N 25
typedef char string[N];
int main(int argc, char *argv[])
{
int i,j;
int jumlah[10];
string inputan;
string temp;
int counter;
//Init
for(i=0;i<10;i++) {
jumlah[i]=0;
}
for(i=0;i<10;i++) {
temp[i]='-';
}
for(i=0;i<10;i++) {
inputan[i]='-';
}
do {
system("cls");
printf("\nMasukan kalimat: ");fflush(stdin);gets(inputan);
if(strcmpi(inputan,"0")!=0) {
strcpy(temp,inputan);
}
getch();
}while(strcmpi(inputan,"0")!=0);
printf("Hasil Analisa:\n\n");
for(i=0;i<10;i++) {
if(temp[i]!='-') {
char c = temp[i];
for(j=0;j<10;j++) {
if(temp[j]!='-') {
if(c == temp[j])
counter+=1;
}
}
jumlah[i] = counter;
counter = 0;
}
}
for(i=0;i<10;i++) {
if(temp[i]!=' ' && temp[i]!='-' && temp) {
printf("\t%c terdapat %d\n",temp[i],jumlah[i]);
}
}
getch();
}
And here's my console result:
So that's make the program will show the space symbol and count it.
And if I can ask again, how to display only one char if there's a symbol again in another index that have same symbol. Thx, forgive me if my English is not fluent.
The space(s) showing up at the end of your printout are because the list of test conditions you include:
if(temp[i]!=' ' && temp[i]!='-' && temp)
May be missing some additional conditions that need to be excluded:
1) added additional test: test[i] != 0
2) changed temp[i] != ' ' to !isspace(temp[i]), which will test against all white space.
Once these are added:
if(!isspace(temp[i]) && temp[i]!='-' && temp && (temp[i] != 0))
The text entered is printed only down to the last non-whitespace character.
Code modifications:
I added some other minor modifications to the following code that allowed the code to be compiled in my environment. Because my modifications use functions that are part of the C standard libraries, this should compile for you as well.
Changes also include expanding for(...) loops to accommodate the array sizes you created, enabling input up to N-1 characters as opposed to only 10. Most of what I did includes commented explanations.
int main(int argc, char *argv[])
{
int i,j;
//int jumlah[10];
int jumlah[N]; // probably meant to use N here?
string inputan = {0};
string temp = {0};
int counter = 0;// initialize
for(i=0;i<N;i++) {
jumlah[i]=0;
}
for(i=0;i<N-1;i++) {
temp[i]='-';
}
for(i=0;i<N-1;i++) {
inputan[i]='-';
}
do {
//system("cls"); This is fine, just does not work in my environment, so commented.
//printf("\nMasukan kalimat: ");fflush(stdin);gets(inputan);
printf("\nPut Sentence (or \"0\" to process): ");fflush(stdin);gets(inputan);// clarified instructions.
if(stricmp(inputan,"0")!=0) { //strcmpi
strcpy(temp,inputan);
}
//getch(); this (or getchar()) is really not necessary here to support
// the flow of your application.
}while(stricmp(inputan,"0")!=0);
printf("Hasil Analisa:\n\n");
for(i=0;i<N;i++) { //replace 10 with N
if(temp[i]!='-') {
char c = temp[i];
for(j=0;j<N;j++) { //replace 10 with N
if(temp[j]!='-') {
if(c == temp[j])
//counter+=1;
counter++; // var++ equivalent var += 1
}
}
jumlah[i] = counter;
counter = 0;
}
}
for(i=0;i<N;i++) {
//if(temp[i]!=' ' && temp[i]!='-' && temp) { // only spaces ?
if(!isspace(temp[i]) && temp[i]!='-' && temp && (temp[i] != 0)) { // temp[i] != 0, and exclude all white space
printf("\t%c terdapat %d\n",temp[i],jumlah[i]);
}
}
getchar(); //orig getch() not standard
}
Addressing your question: how to display only one char if there's a symbol again in another index that have same symbol.
Displaying a list of the characters used, and the number of times used might be better handled in a separate function. The one below can be adapted to be called in your original main function by inserting the following lines:
char *res = letterCounter("this is the string");
printf(res);
free(res);
Just under your existing line: printf("Hasil Analisa:\n\n");
(i.e. replace all your code under that line down to the getch(); function;
char * letterCounter(const char *string)
{
int i, j;
int len = strlen(string);
char *dup = StrDup(string);
if(!dup) return NULL;
int viewableAscii = '~' - '!'; /// range of ASCII from ! to ~ (33 - 126)
char buf[20];
char * results = calloc(100*strlen(string), 1);//ensure enough room
if(!results) return NULL;
/// caps 'A' == 65, 'Z' == 90
/// lowr 'a' == 97, 'z' == 122
/// all visable printables: 33 - 126
unsigned char characterUsageCounter[viewableAscii];
memset(characterUsageCounter, 0,viewableAscii);
for(i=0;i<len;i++)
{
for(j=0;j<viewableAscii;j++)
{
if(dup[i] == 33 + j)
{
characterUsageCounter[j]++;
}
}
}
for(i=0;i<viewableAscii;i++)
{
if(characterUsageCounter[i] > 0)
{
if(characterUsageCounter[i] == 1) sprintf(buf, "%c occurs %d time\n", i+33, characterUsageCounter[i]);
else sprintf(buf, "%c occurs %d times\n", i+33, characterUsageCounter[i]);
strcat(results, buf);
}
}
return results;
}
For example, if the string "this is the string" were passed as the argument to that function, the following would be output: