String Sequence Analyzer - c

First need to convert the string into its individual ASCII value and then we have to accomplish following task:
Check if two consecutive ASCII(values of the string) difference is 1 or not. If difference is 1
then they will be coupled together and print them.
ex.
ABCD
individual ASCII value : 65 67 68 69
Difference of two consecutive ASCII value is 1 so coupled together then print them.
#include<stdio.h>
#include<string.h>
int main(){
char str[100];
int i=0;
printf("Enter any string: ");
scanf("%s",str);
printf("ASCII values of each characters of given string: ");
while(str[i])
printf("%d ",str[i++]);
return 0;
}
This code print the ASCII values but i don't know how to check the difference between two consecutive values and how to couple them.

#include<stdio.h>
int main(){
char str[100]="";
int i, last;
printf("Enter any string: ");
scanf("%s",str+1);//top is dummy
printf("ASCII values of each characters of given string: ");
i = 1;
while(str[i])
printf("%d ",str[i++]);
printf("\n");
last = i;
for(i=1;i<last;++i){
if(str[i] == str[i-1] + 1 || str[i] == str[i-1] - 1 ||
str[i] == str[i+1] + 1 || str[i] == str[i+1] - 1)
printf("%c", str[i]);
}
printf("\n");
return 0;
}

Well to give you a clue and not solve your problem entierly:
As char is an integral type in C, do the following:
if( 'B' - 'A' == 1){
printf("OK\n");
}
if( 'C' - 'A' == 2){
printf("OK\n");
} //etc
(On ideone)
Just think about what should you change in the loop and I think you'll get the idea :)

I think the easiest way to go about your problem it after you read string, create a pointer to it, then just advance a pointer through string checking where *pointer - *(pointer - 1) == 1. Do this for pointer values > string[0] and you can check if your two adjacent characters are coupled. (you will need the absolute value of the difference). A quick hack at your solution would look something like this:
#include<stdio.h>
#include<string.h>
int absdiff (unsigned a, unsigned b) {
if (a == b) return 0;
return (a > b) ? a - b : b -a;
}
int main(){
char str[100];
char cpl[3];
cpl[2]='\0'; // null terminate cpl
//int i=0;
printf("Enter any string: ");
scanf("%s",str);
printf("ASCII values of each characters of given string: \n");
char *ptr = str;
while(*ptr) {
if ((ptr - str) > 0) {
if (absdiff (*ptr, *(ptr - 1)) == 1) {
cpl[0] = *(ptr - 1);
cpl[1] = *ptr;
printf (" coupled : %s\n", cpl);
ptr++;
continue;
}
}
printf(" %c = %u\n",*ptr, *ptr);
ptr++;
}
putchar ('\n');
return 0;
}
And if given the string 'my_dog_is_unable_to_bark.' would produce the following output:
Enter any string: my_dog_is_unable_to_bark.
ASCII values of each characters of given string:
m = 109
y = 121
_ = 95
d = 100
o = 111
g = 103
_ = 95
i = 105
s = 115
_ = 95
u = 117
n = 110
a = 97
coupled : ab
l = 108
e = 101
_ = 95
t = 116
o = 111
_ = 95
b = 98
coupled : ba
r = 114
k = 107
. = 46
Of course you can reformat the output in any manner you like, but for illustrative purposes, this gave a good confirmation of the character -> unsigned int values.

Related

while loops , int vs char reading from scanf , true and false

#include <stdio.h>
int main()
{
int number; // We make 1 int named number
scanf("%d",&number); // We give to number some number xd
while (number!=0)// We made a loop while if number isn't 0 do that
{
printf("text");// print text
scanf("%d",&number); // and get again a number.
// So everything works well beside inserting some char instead of int.
// So what is the problem wont scanf return 0 so we exit the program not
// just printing a text all day? That's my first question.
}
return 0;
}
The second problem is how to make a program reading numbers from keyboard till I enter some special sign for ex '.' Yea we do it with loop while right? But how when scanf("%d",&something) it give me back 0 if I enter everything but number?
change it from scanf int to char
Assumption: You are reading a single char at a time
#include <stdio.h>
int main()
{
char c = "0";
int n = 0;
while (n != 46)// we made a loop while if char isn't '.' ASCII - 46 do that
{
scanf(" %c", &c);
n = (int)c;
printf("text %d", n);
//Add if statement to confirm it is a number ASCII 48 - 57 and use it.
}
return 0;
}
EDIT:
Just some more info on how to use numbers:
input number one by one or just a whole number like 123 with some ending special char like ';' or change the line
scanf(" %c", &c);
to:
scanf("%c", &c);
this way it will register '\n' as ASCII 10
use that with atoi to get the actual int value and use it.
EDIT 2:
#World, you cannot expect to read only numbers and '.'
One way to do this with your own code is:
#include <stdio.h>
int main()
{
char c = "0";
int n = 0;
int number = 0;
while (n != 46)// we made a loop while if char isn't '.' ASCII - 46 do that
{
scanf("%c", &c);
n = (int)c;
if (n>=48 && n<=57) {
number *= 10;
number += (n-48);
}
if (n==10) {
printf("text %d\n", number);
//Use number for something over here
number = 0;
}
}
return 0;
}
EDIT 3:
Logic behind this:
Let's say you enter 341 in the console
the line
scanf("%c", &c);
will read this one by one thus reading '3', '4', '1' and '\n' respectively
the while loop
while (n != 46)
will thus run 4 times where:
1st time
c = '3';
n = 51;
if (n>=48 && n<=57) is true;
number = 0 * 10;
number = number + n - 48 = 0 + 51 - 48 = 3
2nd time
c = '4';
n = 52;
if (n>=48 && n<=57) is true;
number = 3 * 10 = 30;
number = number + n - 48 = 30 + 52 - 48 = 34
3rd time
c = '1';
n = 49;
if (n>=48 && n<=57) is true;
number = 34 * 10 = 340;
number = number + n - 48 = 340 + 49 - 48 = 341
4th time
c = '\n';
n = 10;
if (n>=48 && n<=57) is false;
if (n==10) is true;
it prints "text 341" and sets number to 0
while loop exits when c = '.' and n = 46
how to make a program reading numbers from keyboard till I enter some special sign for ex '.'
When scanf("%d",&number) returns 0, there is some non-numeric input. Read that non-numeric input with alternate code.
#include <stdio.h>
int main() {
while (1) {
int number;
int scan_count = scanf("%d", &number);
if (scan_count == EOF) break; // End-of-file or rare input error.
if (scan_count != 1) {
int ch = fgetc(stdin);
if (ch == '.') break; // Expected non-numeric input to break the loop.
printf("Unexpected input character '%c'\n", ch);
} else {
printf("Expected numeric input: %d\n", ch);
}
} // endwhile
printf("Done\n");
}
A better approach is to ditch scanf() and use fgets()` to read user input. Then process the inputted string.

Palindrome C program convert capital letters to small letters [duplicate]

This question already has answers here:
Implementation of ToLower function in C
(4 answers)
Closed 5 years ago.
At school Im working on a palindrome C program. I'm almost done, but I would like my program to mark both 'Anna' and 'anna' as a palindrome. I tried some stuff out but nothing really worked.
My code :
#include <stdio.h>
#include <string.h>
int main() {
char palindroom[50],a;
int lengte, i;
int woord = 0;
printf("This program checks if your word is a palindrome.\n");
printf("Enter your word:\t");
scanf("%s", palindroom);
lengte = strlen(palindroom);
for (i = 0; i < lengte; i++) {
if (palindroom[i] != palindroom[lengte - i - 1]) {
woord = 1;
break;
}
}
if (woord) {
printf("Unfortunately, %s is not palindrome\n\n", palindroom);
}
else {
printf("%s is a palindrome!\n\n", palindroom);
}
getchar();
return 0;
}
I've seen some people using tolower from ctype.h but I'd like to avoid that.
So my question is : how do I convert all uppers to lowers in a string?
[ps. some words I may code might seem odd, but that's Dutch. Just erase an o and you'll understand]
Thanks.
the difference between uppercase and lowercase in ASCII table is 32 so you can add 32 if an uppercase letter is in the input to convert it to lowercase ( http://www.asciitable.com/ ) :
if ((currentletter > 64) && (currentletter < 91))
{
char newletter;
newletter = currentletter + 32;
str[i] = newletter;
}
else
{
str[i] = currentletter;
}
modified program :
#include <stdio.h>
#include <string.h>
int main() {
char palindroom[50],a;
int lengte, i;
int woord = 0;
printf("This program checks if your word is a palindrome.\n");
printf("Enter your word:\t");
scanf("%s", palindroom);
lengte = strlen(palindroom);
for (i = 0; i < lengte; i++)
{
if (palindroom[i] > 64 && palindroom[i] < 91)
{
palindroom[i] = palindroom[i] + 32;
}
if (palindroom[i] != palindroom[lengte - i - 1]) {
woord = 1;
break;
}
}
if (woord) {
printf("Unfortunately, %s is not palindrome\n\n", palindroom);
}
else {
printf("%s is a palindrome!\n\n", palindroom);
}
getchar();
return 0;
}
65 is the decimal representation of A in the ASCII table, 90 is the decimal representation of Z while a is 97 ( = 65 +32 ) and z is 122 ( = 90 +32 )
If you want don't want to use tolower or toupper you can do this:
// tolower
char c = 'U';
char lower_u = c | 0x20
// toupper
char c = 'u';
char upper_u = c & 0xdf
In ASCII the difference between a lower and an upper character is the 5th bit.
When The 5th bit is 0, you get an upper character, when the 5th bit is 1, you get a lower character.

How to extract multi-digit numbers from a string?

Firstly, I know similar questions have been asked before but I believe my case is different.
My input string is:
(5,7) (1,6) (2,4) (10,14) (8,9)
I wrote the following code for extraction into an array.
main(){
char s[100];
int i=0,x,n=0;
int a[20];
printf("Enter the sets:");
gets(s);
x=strlen(s);
while(i<x){
if((s[i]=='(' && s[i+2]==',') || (s[i]==',' && s[i+2]==')'))
{
a[n]=s[i+1]-'0';
n++;
}
i++;
}
for(i=0;i<n;i++){
printf("%d\n",a[i]);
}
}
The output I get is:
5 7 1 6 2 4 8 9
I understand why my code will skip numbers having 2 or more digits.
Please suggest some minor changes to the present code to fix this limitation.
P.S.- I'm looking for a solution which doesn't depend on length of the number.
Since you only care about the numbers and not any of the delimiters, you can use strtok, which allows for a set of delimiters.
Use the following in place of you existing while loop:
char *p = strtok(s, "(), ");
while (p) {
a[n++] = atoi(p);
p = strtok(NULL, "(), ");
}
Output:
5
7
1
6
2
4
10
14
8
9
If on the other hand you are particular about the format, you can do the following:
char *start = s, *p1 = NULL, *p2 = NULL, *p3 = NULL;
if (start) p1 = strchr(start, '(');
if (p1) p2 = strchr(p1+1, ',');
if (p2) p3 = strchr(p2+1, ')');
while (p1 && p2 && p3) {
a[n++] = atoi(p1+1);
a[n++] = atoi(p2+1);
start = p3+1;
if (start) p1 = strchr(start, '(');
if (p1) p2 = strchr(p1+1, ',');
if (p2) p3 = strchr(p2+1, ')');
}
I have used a different approach to the problem, but I have solved it and it works. Consider trying this. Btw I have used char *s as a string literal but you can keep it like yours.
main(){
char *s="(5,7) (1,6) (2,4) (10,14) (8,9)";
int i=0,x,n=0;
char a[20];
x=strlen(s);
while(i<x){
if (isdigit(s[i])) {
a[n]=s[i];
if (s[i+1]==',' || s[i+1]==')') {
a[n+1]=' ';
n++;
}
n++;
}
i++;
}
printf("%s\n", a);
}
output:
tenshi#mashiro:~/projects/test$ ./test
5 7 1 6 2 4 10 14 8 9
#include <stdio.h>
int main(void) {
// your code goes here
char s[100];
int i=0,x,n=0;
int a[20];
printf("Enter the sets:");
gets(s);
x=strlen(s);
while(i<x-1){
if(isdigit(s[i]))
{
if(isdigit(s[i+1]))
{
a[n]=(s[i]-'0')*10 +(s[i+1]-'0');
i++;
}
else
{
a[n]=s[i]-'0';
}
n++;
}
i++;
}
printf("\n");
for(i=0;i<n;i++){
printf("%d\n",a[i]);
}
return 0;
}
What about the above code, unfortunately C doesn't have simple string functions like split with Regex(it has split function but i didn't understand well). Alternatively, here is ideone for it https://ideone.com/eRKTbD
If the input is in the exact format as in the question, then you can add two loops inside the main while loop to read one set at a time.
while (i < x)
{
if (s[i] == '(')
{
// temporary var to store number
int num = 0;
// read first number
while (s[++i] != ',')
num = num*10 + s[i]-'0';
a[n++] = num;
num = 0;
// read second number
while (s[++i] != ')')
num = num*10 + s[i]-'0';
a[n++] = num;
}
i++;
}
If you always have the same format (a,b)(c,d)...(y,z) and the same number of values then this solution works :
char * arr = "(5,7)(1,6)(2,4)(10,14)(8,9)";
int a,b,c,d,e,f,g,h,i,j;
sscanf(arr,"(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)",&a,&b,&c,&d,&e,&f,&g,&h,&i,&j);
printf("%d %d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i, j);

Simple String Encryption in C

I'm attempting to create a very simple encryption where a string is scanned, and the ascii code is increased by 5 (+5). When the letters reach the end of the alphabet it wraps back around to the beginning (same with numbers). punctuation and any other symbols are not encrypted. The encryption function seems to be working, however I'm having trouble passing the string back to the main function. What has gone wrong?
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*function definitions */
char encrypt(char input_string[]);
int main(void)
{
char input_string[25];
char new_string[25];
char encrypted_string[25];
int i = 0;
// scan word
printf("Enter word: ");
scanf(" %[^\n]", input_string);
fflush(stdin);
//check input
printf("%s\n", input_string);
// call encrypt function
encrypted_string[25] = encrypt(input_string);
// print encrypted version
printf("encrypted: %s\n\n", encrypted_string);
return 0;
}
char encrypt(char input_string[])
{
char new_string;
static char str[25];
int i;
for(i = 0; i < 25; i++)
{
if (input_string[i] > 96 && input_string[i] < 118) // for a - u
{
new_string = (input_string[i] + 5);
}
else if (input_string[i] > 117 && input_string[i] < 123) // for v - z
{
new_string = (input_string[i] - 21);
}
else if (input_string[i] > 64 && input_string[i] < 86) // for A - U
{
new_string = (input_string[i] + 5);
}
else if (input_string[i] > 85 && input_string[i] < 91) // for V - Z
{
new_string = (input_string[i] - 21);
}
else if (input_string[i] > 47 && input_string[i] < 53) // for 0 - 4
{
new_string = (input_string[i] + 5);
}
else if (input_string[i] > 52 && input_string[i] < 58) // for 5 - 9
{
new_string = (input_string[i] - 5);
}
else
{
new_string = input_string[i];
}
str[i] = new_string;
}
printf("\n\n");
i=0;
//check asccii codes
while(str[i])
{
printf("%d ", str[i++]);
}
//print string
printf("\n\n%s\n\n", str);
//return string to main
return(str[25]);
}
return(str[25]); means you're trying to return the value of the 26th element,[which is out-of-bound access], not the address of the string.
encrypted_string[25] = encrypt(input_string);
No, you cannot assign a string return like that. It's wrong in many ways.
To correct, follow the below steps.
change char encrypt(char input_string[]) to char* encrypt(char input_string[])
use return(str); instead of return(str[25]);
instead of char encrypted_string[25];, write char * encrypted_string;
NOTE:
using static array will do the job, but IMO, a better approach will be allocating the array dynamically and return the pointer after populating from encrypt() function. You can later free() the pointer from main().
Your function:
char encrypt(char input_string[])
literally says that it accepts a long string as input, and returns just a single character as output.
That seems very dubious.
Don't you want it to return a string as output, not just one letter?

Performing arithmetic on Characters in C

I am trying to write a program that adds, subtracts, multiplies, and divides a string of characters. Where I'm at now with the program is figuring out how to split the input string into two strings, and then perform the appropriate +-/*.
The input should look like this abc+aaa
and the output for that should be abc + aaa = bcd
How do I convert character strings into integer strings?
#include <stdio.h>
#include <math.h>
#include <string.h>
int main() {
printf("This is a pseudo arithmetic program");
char input[10];
input[10] = '\0';
char first [9];
first[9] = '\0';
char last [9];
last[9] = '\0';
int i = 0;
int b;
int e;
while (input[0] != '0') {
if (input[0] == 0){
return -1;
}
printf("\nEnter a math problem in SOS format using only lowercase letters up to 9 characters");
printf("\nEx: abc+abc... type '0' to quit \n");
scanf("%s", input);
int x = 0;
x = strlen(input);
if (strchr(input, '+')){
for (i = 0; i <= x; i++) {
if (i == '+')
strncpy(first, &input[0], i-1);
i = 0;
}
for (i = x; i >= input[0]; i--) {
if (i == '+')
strncpy(last, &input[i], x);
i = 0;
}
printf("%s", first);
printf(" + ");
printf("%s", last);
printf(" = %d", first + last);
}
There seems to be multiple problems with your code:
There is a array out of bounds happening for almost all the arrays:
char input[10];
input[10] = '\0';
In this if you want to initialize the last character with '\0' then it should be
input [9] = '\0'
Arrays indexes always start from 0.
It is not clear what is the use of below lines:
while (input[0] != '0') { if (input[0] == 0){ return -1; }
When taking input for a string, why are prompting users to enter a 0 to end it?
strrchr returns the pointer from where the searched character begins. So, you can that itself to determine where the '+' symbol is and two split the strings instead of your while loop. See strrchr man page
Also, your idea of adding characters is not clear. From your example, it appears you are considering a = 1, b = 2 etc. In such a case, if your code is case insensitive, then you can convert all your input to upper case and then do (input[0] - 'A')+1 to convert your letters like a, b, c to 1, 2, 3 etc.
Hope these pointers help. Suggest you check your problem statement again and refactor your code accordingly.

Resources