Spaces and adjacent letters - c

i have 2 exercises that i need to do i did most but i am stuck now .
for the first one i need the pc to detect spaces and if there is to type incorrect input but idk how can i let the pc detect them .
for the second i need it to type if there are two letters adjacent in the alphabet
example 8#a8d?g.## i need it to type ad . another example 7mK#e*gb!c type (eg) plus if they are already types in the first line then type No such two letters
like b?a0a the first line b?a0a should be the answer and second line if there are 2 letters adjacent (they have same answer)so type No such two letters.
the second question should order the alphabet and if there already is 2 letters in order then type them .
first Qs:-
#include<stdio.h>
#include<conio.h>
#include <math.h>
int main()
{
int a, b, c, d, e, f, decimal;
printf("Enter 5 bits");
scanf("%d", &a);
b = a / 10000;
c = a % 10000 / 1000;
d = a % 1000 / 100;
e = a % 100 / 10;
f = a % 10;
if (b <= 1)
if (c <= 1)
if (d <= 1)
if (e <= 1)
if (f <= 1)
{
f = f*1;
e = e*2;
d = d*4;
c = c*8;
b = b*16;
decimal = b + c + d + e + f;
printf(" your decimal value is %d",decimal);
}
else
{
printf("incorrect output");
}
getch();
2) second Question :-
#include<stdio.h>
#include<string.h>
#include<conio.h>
int main()
{
char string[100];
int length;
int i;
char largest = 96; // Init to a value not in ASCII table
char smallest = 121; // Init to a value not in ASCII table
printf("enter string number ");
scanf("%d", &length);
printf("enter the string ");
scanf("%s", string);
//length = strlen(string);
for (i = 0; i < length; i++) {
if (string[i] >= 'a' && string[i] <= 'z') {
if (string[i] < smallest) {
smallest = string[i];
}
if (string[i] > largest) {
largest = string[i];
}
}
}
for (i = smallest; i <= largest; i++) {
printf("%c", i);
}
printf("\n");
getch();
}
Thanks everyone for your help.

Related

Mistake in CS50 Readability project with only 1 input, all others work

I seem to have made a mistake in my code but I can't find it.
All reading grades give me the correct grade, except for grade 7 which results in grade 8.
I assume it is a rounding error of some sort?
I tested the following piece of code with and without the round() in the last function.
Without it most of the grade levels are off, with the round() in there I only get an mistake a the grade7 level.
Where is my mistake?
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
//Prototypes
int count_letters(string text);
int count_words(string text);
int count_sentences(string text);
int get_score (string text);
//Main function
int main(void)
{
//Get user input
string text = get_string("Text: ");
//Grade user text
int i = get_score(text);
if(i < 1)
{
printf("Before Grade 1\n");
}
else if (i > 1 && i < 16)
{
printf("Grade %i\n", i);
}
else
{
printf("Grade 16+\n");
}
}
// Extra functions
int count_letters(string text)
{
// variables
int letters = strlen(text);
int total_letters = 0;
int characters = 0;
// Loop through text and count all non-letters
for(int i = 0; i < letters; i++)
{
if((text[i] < 65 || text[i] > 95) && (text[i] < 97 || text[i] > 122))
{
characters++;
}
}
// substract all non-letters from total chars and return.
total_letters = letters - characters;
return total_letters;
}
int count_words(string text)
{
// variables
int letters = strlen(text);
int spaces = 1;
// Loop through text and count all spaces
for(int i = 0; i < letters; i++)
{
if(text[i] == ' ')
{
spaces++;
}
}
return spaces;
}
int count_sentences(string text)
{
// variables
int letters = strlen(text);
int sentence = 0;
// Loop through text and count all sentences
for(int i = 0; i < letters; i++)
{
if(text[i] == 46 || text[i] == 33 || text[i] == 63)
{
sentence++;
}
}
return sentence;
}
int get_score (string text)
{
//variables
int letters = count_letters(text);
int words = count_words(text);
int sentence = count_sentences(text);
float index = 0;
// letters divided by words * 100
float L = 100 * letters / words;
// sentences divided by words *100
float S = 100 * sentence / words;
index = round(0.0588 * L - 0.296 * S - 15.8);
return index;
}
if((text[i] < 65 || text[i] > 95) && (text[i] < 97 || text[i] > 122)) is almost certainly a bug. You probably meant to be implementing isalpha, but you did it incorrectly. You meant to write:
if((text[i] < 'A' || text[i] > 'Z') && (text[i] < 'a' || text[i] > 'z')), which would have avoided the typo in which 95 was used instead of 90. Instead of this, though, you should just use the standard library and write:
if( ! isalpha(text[i]) ) ...
Using literals like 'A' instead of the magic number 65 makes the code more readable and helps avoid trivial mistakes like this.
There are quite a few issues with your code:
As #IrAM has mentioned in a comment, your if does not handle a score of 1. Moreover, you can simplify your if checks if you start from the other end, i.e. first check for greater than 16:
int main(void)
{
//Get user input
string text = get_string("Text: ");
//Grade user text
int i = get_score(text);
if(i > 16)
{
printf("Grade 16+\n");
}
else if (i > 0)
{
printf("Grade %i\n", i);
}
else
{
printf("Before Grade 1\n");
}
}
As #Gerhardh mentions, you are dividing two integers which forces the result to be an integer too. If at least one of the operands is casted to a float, the result is type-promoted to a float:
// letters divided by words * 100
float L = 100 * (float) letters / words;
// sentences divided by words *100
float S = 100 * (float) sentence / words;
Optimizations
You have three different functions for counting words, sentences and letters. Why three loops when you can do it in one loop? Plus an additional iteration for strlen() in each function. Write a Count struct like this:
struct Count
{
int letters;
int words;
int sentences;
int length;
};
Then have one function that returns this struct. Like #WilliamPursell mentions, using character literals instead of ASCII values makes code much more readable:
Count get_count(string text)
{
Count result = {0, 1, 0, 0};
result.length = strlen(text);
int characters = 0;
// Loop through text and count all non-letters
for(int i = 0; i < count.length; i++)
{
if((text[i] < 'A' || text[i] > 'Z') && (text[i] < 'a' || text[i] > 'z'))
{
characters++;
}
if(text[i] == ' ')
{
result.words++;
}
if(text[i] == '.' || text[i] == '!' || text[i] == '?')
{
result.sentences++;
}
}
// subtract all non-letters from total chars and return.
count.letters = count.length - characters;
return result;
}
This is what get_score() will change to:
int get_score (string text)
{
//variables
Count result = get_count(text);
float index = 0;
// letters divided by words * 100
float L = 100 * (float) result.letters / result.words;
// sentences divided by words *100
float S = 100 * (float) result.sentences / result.words;
index = round(0.0588 * L - 0.296 * S - 15.8);
return index;
}
Side Note: A '.' may always not necessarily mean the end of a sentence. It has other meanings like in an acronym or as ellipsis.

How does this code convert between bases?

#include<stdio.h>
#include<string.h>
void baseconversion(char s[20], int, int);
main()
{
char s[20];
int base1, base2;
printf("Enter the number and base:");
scanf("%s%d", s, &base1);
printf("Enter the base to be converted:");
scanf("%d", &base2);
baseconversion(s, base1, base2);
}
void baseconversion(char s[20], int b1, int b2)
{
int count = 0, r, digit, i, n = 0, b = 1;
for(i = strlen(s) - 1; i >= 0; i--)
{
if(s[i] >= 'A' && s[i] <= 'Z')
{
digit = s[i] - '0' - 7;
}
else
{
digit = s[i] - '0';
}
n = digit * b + n;
b = b * b1;
}
while(n != 0)
{
r = n % b2;
digit = '0' + r;
if(digit > '9')
{
digit += 7;
}
s[count] = digit;
count++;
n = n / b2;
}
for(i = count - 1; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
I know this code converts chars to integers, but I've never seen it before, never used C.
If someone could explain a bit of what's going on with the conversions I'd appreciate it, thank you.
I understand that at some point the digits get reversed.
It does it through two steps, the first one is converting the number into its decimal form, in this part:
for(i = strlen(s) - 1; i >= 0; i--) //Start from right to left
{
if(s[i] >= 'A' && s[i] <= 'Z')
digit = s[i] - '0' - 7; //Get the integer equivalent to the letter
else
digit = s[i] - '0'; //Get the integer equivalent to the numerical character
n = digit * b + n; //Add the value of this character at this position
b = b * b1; //The value of the next character will be higher b times
}
Then it transforms the result to the desired base, in this part:
while(n != 0)
{
r = n % b2; //The remaining will be the rightmost value for the new base
digit = '0' + r; //Get the integer for the new digit
if(digit > '9')
digit += 7; //Here the digit will be a letter
s[count] = digit;
count++;
n = n / b2; //Remove the rightmost digit to get the next one
}

Problem Scanning Integers with Comma Between Them into a 2d Array

I am trying to write a C program that accepts a 2d matrix in the form of axb:{{a,b,c},{d,e,f}...} where a determines the number of rows and b determines the number of columns, the subunits {} declaring rows and the elements of rows are declared as a,b,c... between {}. The problem is the program only accepts matrices without commas between the elements so only matrices in the format axb:{{a b c},{d e f}...}} work. I want the program to be able to accept an input with commas between the variables. Here is the code for reference:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int a,b;
scanf("%dx%d:{", &a, &b);
int matrix[a][b];
int r,c;
for (r = 0; r < a; r++) {
scanf("{%d", &matrix[r][0]);
for(c = 1; c < (b -1); c++) {
scanf("%d", &matrix[r][c]);
}
scanf("%d},", &matrix[r][c]);
}
printf("%dx%d:{", b, a);
for (c = 0; c < (b - 1); c++) {
printf("{");
for(r = 0; r < (a - 1); r++) {
printf("%d,",matrix[r][c]);
}
printf("%d",matrix[r][c]);
printf("},");
}
printf("{");
for(r = 0; r < 3; r++) {
printf("%d,",matrix[r][c]);
}
printf("%d",matrix[r][c]);
printf("}");
printf("}\n");
return 0;
}
What I would do is scan the whole input and work with that afterwards.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// scan the input matrix
int a, b;
char input[256];
scanf("%dx%d:%256[^\n]", &a, &b, input);
int mat[a][b];
// populate matrix:
char* p = input;
int i = 0;
while (p != input + 256)
{
// scan until the character is not a separator
if (*p == '{' || *p == '}' || *p == ',')
{
++p;
}
else
{
int n;
sscanf(p, "%d", &n);
mat[0][i] = n;
++i;
// scan until we find a separator character
while (p != input + 256 && (*p != '{' && *p != '}' && *p != ','))
{
++p;
}
if (i >= a*b)
break;
}
}
printf("your matrix:\n");
for (i = 0; i < a*b; ++i)
{
if (i % b == 0)
printf("\n");
printf("%d ", mat[0][i]);
}
printf("\n");
return 0;
}
Example input and output:
Input:
3x2:{{a, b},{c, d},{e, f}}
Output:
a b
c d
e f
where a, b, c, d, e and f are numbers (well, integers).
However this might not be an elegant solution, but it does what you'd asked for.
At the least it can give you some ideas. Hope this can be of help.
Note:
When indexing the array I used a single index i. You can do this because arrays like these are stored in an 1D array anyway. However this is just my laziness. Feel free to correct it.
If this is not what you had in mind or I made some mistakes feel free to correct me. Might have misunderstood something.

How do i add an "(if)" that allows only letters between a-f || A-F?

I wrote a program that does conversion from hex to decimal. all I got left is to check if the char is between a-f or A-F, maybe 0-9 as well. if it is not between them it will print "Illegal input".
My code:
int n, i;
char currentDigit;
unsigned long int sum, currentDigitInt;
printf("Enter the number of digits in the Hexadecimal number:");
scanf_s("%d", &n);
sum = 0;
printf("Enter the Hexadecimal number:\n");
for (i = n - 1; i >= 0; i--) {
scanf_s(" %c", &currentDigit);
if (currentDigit >= 'a') {
currentDigitInt = (currentDigit - 'a') + 10;
}
else if (currentDigit >= 'A') {
currentDigitInt = (currentDigit - 'A') + 10;
}
else
currentDigitInt = currentDigit - '0';
sum += currentDigitInt * pow(16, i);
}
printf("The decimal number is: %u", sum);
The output I need:
Enter the number of digits in the Hexadecimal number: 2
Enter the Hexadecimal number: QQ
Illegal input
There are several problems with the code.
For starters the function scanf_s shall include as a parameter the size of buffer for the format specifier c.
To output an object of the type unsigned long you have to use the format specifier ul.
In these if statements you do not check the upper limit of valid alpha hexadecimal digits.
if (currentDigit >= 'a') {
currentDigitInt = (currentDigit - 'a') + 10;
}
else if (currentDigit >= 'A') {
currentDigitInt = (currentDigit - 'A') + 10;
}
To check whether an entered symbol is a valid hex digit you should write a separate function.
Here is a demonstrative program that shows how it can be done.
//Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int hex_digit( char c )
{
const char *alpha = "ABCDEF";
unsigned char c1 = toupper( ( unsigned char )c );
const char *p;
int result = -1;
if ( '0' <= c1 && c1 <= '9' )
{
result = c1 - '0';
}
else if ( c1 != '\0' && ( p = strchr( alpha, c1 ) ) != NULL )
{
result = *p - alpha[0] + 10;
}
return result;
}
int main(void)
{
const unsigned long HEX_BASE = 16;
unsigned int n;
printf( "Enter the number of digits in the Hexadecimal number: " );
scanf_s("%u", &n);
unsigned long sum = 0;
if ( n )
{
printf( "Enter the Hexadecimal number: " );
unsigned int i = 0;
for ( ; i < n; i++ )
{
char c;
scanf_s( " %c", &c, 1 );
int digit = hex_digit( c );
if ( digit < 0 ) break;
else sum = sum * HEX_BASE + digit;
}
if ( i == n )
{
printf("The decimal number is: %ul\n", sum);
}
else
{
puts( "Illegal input" );
}
}
return 0;
}
Its output might look the following way
Enter the number of digits in the Hexadecimal number: 8
Enter the Hexadecimal number: ffFFffFF
The decimal number is: 4294967295l
If you want you can add a check in the program that the specifird number of inputted hexadecimal digits is not greater than 2 * sizeof( unsigned long ).
There are multiple problems in your code:
you can test character ranges with the && operator. For example:
if (currentDigit >= 'a' && currentDigit <= 'f')
you combine these tests in a series of if / else and complain if none of the tests match.
note also that the expression for sum is incorrect too. sum += currentDigitInt * pow(16, i); should be;
sum = sum * 16 + currentDigitInt;
the printf format for unsigned long is %lu, not %u.
you should test the return value of scanf_s to properly detect a potential end of file.
scanf_s expects 2 extra arguments for conversion specifier %c and may not be available on all systems.
note too that you do not need to ask for the number of hex digits, just break from the loop when the character entered is a newline for the second time.
Here is a corrected version:
#include <stdio.h>
int main() {
int currentDigit;
unsigned long int sum;
int invalid = 0;
printf("Enter the Hexadecimal number: ");
sum = 0;
while ((currentDigit = getchar()) ! EOF && currentDigit != '\n') {
int currentDigitInt;
if (currentDigit >= 'a' && currentDigit <= 'f') {
currentDigitInt = (currentDigit - 'a') + 10;
} else
if (currentDigit >= 'A' && currentDigit <= 'F') {
currentDigitInt = (currentDigit - 'A') + 10;
} else
if (currentDigit >= '0' && currentDigit <= '9') {
currentDigitInt = currentDigit - '0';
} else {
invalid = 1;
continue; // keep scanning the input until end of line
}
sum = sum * 16 + currentDigitInt;
}
if (invalid) {
printf("Invalid input\n");
} else {
printf("The decimal number is: %lu\n", sum);
}
return 0;
}
Notes:
The C standard does guarantee that 0 through 9 are consecutive but purists will argue that the letters a through f and A through F might not be consecutive the execution character set. While the are correct, obscuring newbie programmers with these considerations is counter productive and quite excessive as these character ranges are consecutive in both ASCII and EBCDIC (the gaps in EBCDIC are between i and j and between r and s in both cases).
a (A) to f (F) need not be consecutive in C.
If you want your program to run on all implementations of C (klingon space-ship, DS9K, Mars Rover, ..., ...) you could try something like this
if ((currentdigit == 0) || (strchr("0123456789abcdefABCDEF", currentdigit) == NULL)) /* invalid */;
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int isaTof(int c)
{
c = toupper(c);
if(c >= 'A' && c <= 'F') return 1;
return 0;
}
int isin(int c, const char *allowedchars)
{
return strchr(allowedchars, c) != NULL;
}
int isHEXNumber(const char *number)
{
const char allowedchars[] = "abcdefABCDEF0123456789";
while(*number)
{
if(!isin(*number++, allowedchars)) return 0;
}
return 1;
}
or nitpickers version
int isHEXNumber(const char *number)
{
const char allowedchars[] = "abcdefABCDEF0123456789";
if(!number || |*number) return 0;
while(*number)
{
if(!isin(*number++, allowedchars)) return 0;
}
return 1;
}
int main()
{
const char allowedchars[] = "abcdefABCDEF0123456789";
printf("%s\n", isin('d', allowedchars) ? "Yes" : "No");
return 0;
}

C - Read in float value using getchar and print out float using printf

I'm extremely lost and confused.
I have to read in a float integer like 3.432 using getchar. Then, I have to print it out again as a float with a precision of 4 decimal places using printf. So 3.432 --> 3.4320 and .450 --> .4500, and 453 --> 453.0000.
I've been using getchar() and I understand that, but trying to reconvert the value as a float is where I'm just extremely lost.
float num = 0.0;
char ch;
while((ch = getchar()) != '\n'){
num = ch - '0';
printf("%.4f", num);
}
I know why that is wrong and what it outputs but that's what I have so far
EDIT: I can only use getchar to read the float values
Not tested (no time). Hope it helps.
#include <stdio.h>
int main(void)
{
float num = 0.0;
float i = 1.0;
char ch;
printf("Enter a float number: ");
while((ch = getchar()) != '\n')
{
if (ch == '.')
{
i = 0.1;
}
else if ((ch>= '0') && (ch <='9'))
{
if (i==1)
{
num *= 10;
num += ch - '0';
}
else
{
num += (ch - '0') * i;
i /= 10;
}
}
}
printf("%.4f\n", num);
return 0;
}
Ok, so you should first specify what you want - as usual keep away from the keybord until you exactly know what you want to build:
read until end of file or first new line
skip initial blank characters (optional but not expensive)
ignore trailing blank character (optional but not expensive)
reject any non blank after first trailing blank
reject any character other than blanks, digits and dot
process the integer part (until first dot) but multiplying current value by 10 and adding character code minus char '0'
ensure at most one dot
process the decimal part by adding char - '0' multiplied by 0.1 power decimal position
Once that has been stated coding is simple and could be:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void error(int pos, char c) {
fprintf(stderr, "Unwanted character %c at %d\n", c, pos);
exit(1);
}
int main() {
double f = 0.;
int c;
bool initial = 1, final=0;
int pos = 0;
double decimal = 0;
while (((c = getchar()) != EOF) && (c != '\n')) {
pos += 1;
if (isspace(c)) { // accept spaces before and after the number
if (initial || final) continue;
else {
final = 1;
continue;
}
}
else if (final) { // do not accept anything after a space after the number
error(pos, c);
}
initial = 0; // at least one non blank char
if (c == '.') {
if (decimal) { // accept only one decimal dot
error(pos, c);
}
else decimal = 1;
}
else if (! isdigit(c)) { // only digits
error(pos, c);
}
else if (decimal == 0) {
f = f * 10 + c - '0'; // integer part
}
else {
decimal *= .1; // fractional part
f += (c - '0') * decimal;
}
}
printf("%.4f\n", f);
return 0;
}
As a bonus I showed you how to process error conditions
It would be simpler if you first write a function reading integer.
Then you can think about writing a function reading the decimal part and combine the result.
Also, you need to accumulate the read information. At the moment you are overwriting previously read digit with a new one.
Another possibility using only stdio in solving the task could be a simple two-step process:
declaring and reading the input into a character array, using some more or less sophisticated fool-proofing
"parsing" the array members on the left and right hand side of the decimal point and multiplying the ('0' offset subtracted value) by the corresponding power of 10.
_
#include <stdio.h>
int main(void)
{
float power_of_ten, num = 0.;
char c, ch[32];
int j, i = 0;
int point_pos = -1; //initialize decimal point position 'offscale'
while(((c = getchar()) != EOF) && (c != '\n')) //simple fool-proof check
if(((c >= '0')&&(c <= '9')) || (( c == '.')&&(point_pos == -1))){
ch[i] = c;
if(ch[i] == '.')
point_pos = i;
i++;
}
ch[++i] = '\0'; //length of the array
//parsing the array
if(point_pos >= 0){ //to the right of decimal point
power_of_ten = .1;
for(j = point_pos + 1; j < i-1; j++){
num += (float)(ch[j] - '0')*power_of_ten;
power_of_ten *= .1;
}
}
power_of_ten = 1.; //to the left of decimal point
if(point_pos == -1)point_pos = i-1;
for(j = point_pos - 1; j >= 0 ; j --){
num += (float)(ch[j] - '0')*power_of_ten;
power_of_ten *= 10;
}
printf("%.4f\n", num);
return 0;
}
Hope this helps!!
#include<stdio.h>
#include<string.h>
#include<math.h>
int findNumOfDigits(int num);
int main(void)
{
char c;
float f, mod, fractional;
char *buff = malloc(10), *fptr;
char *str = buff;
int digits;
printf("Enter any number\n");
c = getchar();
while(c!='\n')
{
*buff = c;
buff = buff+1;
c = getchar();
}
*buff = '\0';
mod = atoi(str);
fptr = strstr(str, ".");
if(fptr!=NULL)
fptr++;
fractional = atoi(fptr);
digits = findNumOfDigits(fractional);
f = (mod + (fractional/pow(10,digits)));
printf("Number converted to float = %f", f);
return 0;
}
int findNumOfDigits(int num)
{
int i;
for(i = 1; num >= 10; i++)
{
num = num/10;
}
return i;
}

Resources