This is my first question on this forum and it is rather tricky.
I am working on a problem in C where you are entering characters,until you enter the sign !. Then you have to extract the numbers and print their sum.
The input is in the format :
adasdas12fef 1 asdasdas43 da3 23adead
The output should be : 82 ( 12+1+43+3+23)
Note: The usage of string is forbidden.
I am sorry for the bad language.
If there are any questions about other details or usages, feel free to comment.
I think this will work for you :
#include <stdio.h>
int main(void) {
// declear and initialize the variables
char input[200];
char c;
int i = 0, j = 0, sum = 0, num = 0, next = 0;
// get input until '!' is pressed
while((c=fgetc(stdin)) != '!') {
input[i] = c;
i++;
}
// end string
input[i] = '\0';
// loop through the string
// if numeric found, will add to sum.
// for 2 numeric (one after another) will multiply
// previous one with 10 and add with the current one
for (j = 0; j < i; j++) {
if (next == 1) {
next = 0;
num = input[j-1] - '0';
num *= 10;
num += (input[j] - '0');
sum += num;
continue;
}
if (input[j] >= '0' && input[j] <= '9') {
if (input[j+1] >= '0' && input[j+1] <= '9') {
next = 1;
} else {
sum += (input[j] - '0');
}
}
}
printf("sum: %d\n", sum);
}
Please do not ask for full code. I found the problem interesting, that's why I did it. Try first, then ask if you face any specific problem.
How about some pseudo code to get you started?
state = spaces
number = 0
Forever {
Get ch
if (ch == EOF or `!`) {
if (state == num) print number
break;
}
if (state == space) {
if (ch is a digit) {
number = digit
state = num
}
} else {
if (ch is a digit) {
number = number * 10 + digit
} else if (ch is a space) {
print number
state = space
number = 0
}
}
}
Related
I have a function that counts the number of unique characters in a 2D array by looping over it and increasing the count in each cell of a 1D array by 1 each time a character from the valid char array is found. I then loop over the 1D array and each time a cell with a number higher than 0 is found, a counter is increased. If this number is higher than the height/width of my structure, it returns false.
'.' represents an empty space and whilst it is valid in the scheme of the program, it should not count as a unique character.
I was wondering if there was a way to create a function with the same functionality, but much shorter.
bool uniqueChars (Bookcase *b)
{
int i, j, chars[8] = {0}, cnt = 0;
char validChars[10] = {"KRGYBMCW."};
bNullPoint(b);
for (i = 0; i < b->height; i++) {
for (j = 0; j < b->width; j++) {
b->shelves[i][j] = toupper(b->shelves[i][j]); /* To aid with testing*/
if (strchr(validChars, b->shelves[i][j])) {
if (b->shelves[i][j] == 'K') {
chars[0] += 1;
}
if (b->shelves[i][j] == 'R') {
chars[1] += 1;
}
if (b->shelves[i][j] == 'B') {
chars[2] += 1;
}
if (b->shelves[i][j] == 'G') {
chars[3] += 1;
}
if (b->shelves[i][j] == 'C') {
chars[4] += 1;
}
if (b->shelves[i][j] == 'Y') {
chars[5] += 1;
}
if (b->shelves[i][j] == 'W') {
chars[6] += 1;
}
if (b->shelves[i][j] == 'M') {
chars[7] += 1;
}
} else {
return false;
}
}
}
for (i = 0; i < 8; i++) {
if (chars[i] > 0) {
cnt += 1;
}
}
if (cnt > b->height) {
return false;
}
return true;
}
Declare a character array or a string literal as for example
const char *letters = "KRBGCYQM.";
and then use the standard string function strchr declared in the header <string.h> like
char *p = strchr( letters, b->shelves[i][j] );
if ( p != NULL )
{
if ( b->shelves[i][j] != '.' ) ++chars[p - letters];
}
else
{
return false;
}
Pay attention to that it is unclear for readers of your code why the character '.' is included though it is not counted.
Can I suggest bit-fields instead of the chars array? Something like this:-
present = 0
foreach char c in b->shelves
if c is a uppercase letter
present |= 1 << (c - 'A')
present &= valid letters bit pattern (this is a constant and is the or of 1 shifted by each letter)
return number of bits in present <= b->height
Alternatively, if you don't like that, use a switch rather than the sequence of if tests:-
switch b->shelves[i][j]
case 'K'
++chars[0]
other cases for the valid letters
++chars[whatever]
default:
error - an invalid character
I try to create atoi function, and think I made right code, but when I run it, it shows wrong one. I'm trying to figure it out, but don't know what I made it wrong please check the code and give some help
My code is
#include <stdio.h>
int my_atoi(char *str)
{
int i;
int res;
int sign;
i = 0;
res = 0;
sign = 1;//sign of '-' or '+'
while(str[i] == ' ' || (str[i] >= 9 && str[i] <= 13))
{
i++;
}
if(str[i] == '-')
{
sign = -1;
i++;
}
else if(str[i] == '+')
{
sign = 1;
i++;
}
while(str[i] >= '0' && str[i] <= '9')
{
res = res * 10 + str[i] + '0';
i++;
}
return(res * sign);// to make integer which has value of '-' or '+'
}
int main(void)
{
char str[] = "-2018shiba";
printf("%d\n", my_atoi(str));
return(0);
}
When I run it, it shows -108674
I am seeing multiple mistakes here.
If you want to convert a ASCII character into the corresponding integer you need to subtract '0'. Take a look at the ASCII table: for instance '7' is mapped by decimal value 55. Hence if you want to get 7 then you need to subtract the ASCII of '0' which is 48 (55 - 48 = 7):
int foo = str[i] - '0';
In the very last while loop of my_atoi. The value of an indexed numeral string representation is calculated by multiplying the value of str[i] with the numerical base to the power of the index starting from behind.
For example lets take a look at "1337":
7*10^0 + 3*10^1 + 3*10^2 + 1*10^3 = 7 + 30 + 300 + 1000 = 1337
As you can see, the 7 has the numerical index 0 and so on. Assuming you want to just ignore shiba your code be looking something like this:
#include <stdio.h>
#include <string.h>
// Return base^(exponent)
int my_pow(int base, unsigned int exponent)
{
if (exponent == 0) {
return 1;
} else {
int result = base;
for (int i = 1; i < exponent; i++) {
result *= base;
}
return result;
}
}
int my_atoi(char *str, size_t len)
{
int i;
int res;
int sign;
i = 0;
res = 0;
sign = 1;//sign of '-' or '+'
while(str[i] == ' ' || (str[i] >= 9 && str[i] <= 13))
{
i++;
}
if(str[i] == '-')
{
sign = -1;
i++;
}
else if(str[i] == '+')
{
sign = 1;
i++;
}
// Store the index where the number string starts
int j = i-1;
// Find the ending index of the number string
i = len;
while (str[i] < '0' || str[i] > '9') {
i--;
}
int num_end = i;
// Now start at the ending
while(i > j)
{
if (str[i] >= '0' && str[i] <= '9') {
res += my_pow(10, num_end-i) * (str[i] - '0');
} else {
// If a character unequal to a digit is found then skip it
num_end--;
}
i--;
}
return(res * sign);// to make integer which has value of '-' or '+'
}
int main(void)
{
char str[] = "-2018shiba";
printf("%d\n", my_atoi(str, strlen(str)));
char str2[] = "-20X18shiba";
printf("%d\n", my_atoi(str2, strlen(str2)));
return(0);
}
I am new to C and trying to Write a program that reads in a series of integers until a value of zero is encountered and then prints the sum of all the numbers except those that are equal to 13 or that come immediately after a 13. It is guaranteed that there is at least one zero in the input.
At most 100 lines of input, each line containing a single integer. At least one of the lines will contain the integer 0.
My code is like this:
#include <stdio.h>
int main ()
{
int sum = 0;
int data[100];
int i = 0;
scanf("%d\n", &data[i]);
while (data[i] != 0 && i < 100) {
if (data[i] == 13) {
sum = sum;
} else if (i > 0 && data[i-1] == 13) {
sum = sum;
} else {
sum += data[i];
i++;
}
scanf("%d\n", &data[i]);
}
printf("%d",sum);
}
I tried to get rid of the number after 13 but failed... Please help.
You could also try this:
// extra flag outside loop
int found13 = 0;
while (data[i] != 0 && i < 100) {
if (data[i] == 13) {
found13 = 1; // set flag
} else if (found13) {
found13 = 0; // clear flag
} else {
sum += data[i];
i++;
}
scanf("%d\n", &data[i]);
}
Improvements:
Doesn't peek back at the previous element
Doesn't need to constantly check i > 0):
EDIT: further refactor
int sum = 0;
int found13 = 0;
int data;
while (scanf("%d\n", &data) == 1 && data != 0) {
if (data == 13) {
found13 = 1; // set flag
} else if (found13) {
found13 = 0; // clear flag
} else {
sum += data;
}
}
Improvements:
As #PaulOgilvie pointed out, you no longer need an array to store your results
... neither do you need i
... nor the extra call to scanf outside the loop
Now works for any number of inputs
It is easiest to collect all conditions in one boolean expression of the if-statement:
if (data[i] != 13 && (i == 0 || data[i-1] != 13){
sum += data[i];
}
i++;
... and move i outside the if body.
I need to know how to convert a user input, which is a string, to a double. like if he writes in the string "23.45", it converts into double 23.45
(without any library functions).
I already got this code for integer, but don't know how to continue with double:
#include <stdio.h>
void main()
{
char input[100];
printf("Type a String which will be converted to an Integer: ");
scanf("%s", input);
int number = 0;
int i = 0;
if (input[i] >= 48 && input[i] <= 57)
{
while (input[i] >= '0' && input[i] <= '9')
{
number = number * 10;
number = number + input[i] - '0';
i++;
}
printf("string %s -> number %d \n", input, number);
}
else
{
printf("Enter a number! \n");
}
}
There's probably no reason why you'd roll out your own version of this, as strtod in stdlib.h already covers all manner of formats.
Here's a version which covers signed numbers as input and has some hints of where more suitable error handling could be placed:
#include <stdbool.h>
static void halt_and_catch_fire (void);
double strtod_homebrewn (const char* str)
{
double result = 0;
// handle signs:
bool is_negative = false;
if(*str == '-')
{
is_negative = true;
str++;
}
else if(*str == '+')
{
str++;
}
// handle the dot position:
bool is_dot_found = false;
double multiplier = 0.1;
// the actual conversion:
for(const char* s=str; *s!='\0'; s++)
{
if(*s >= '0' && *s <= '9') // ctype.h isdigit() would be preferred here
{
if(is_dot_found)
{
result += (*s - '0') * multiplier;
multiplier /= 10;
}
else
{
result *= 10;
result += *s - '0';
}
}
else if(*s == '.')
{
if(is_dot_found) // two dots?
{
halt_and_catch_fire(); // replace this with error handling
}
is_dot_found = true;
}
else if(*s != '\0') // all cases tested, some weird unknown character found
{
halt_and_catch_fire(); // replace this with error handling
}
}
if(is_negative)
{
result = -result;
}
return result;
}
static void halt_and_catch_fire (void)
{
halt_and_catch_fire();
}
#include <stdio.h>
void main()
{
char input[100];
printf("Type a String which will be converted to a double: ");
scanf("%s", input);
double number = 0.0;
double divider = 1.0;
int inFraction = 0;
int i = 0;
if (input[i] >= 48 && input[i] <= 57)
{
inFraction = 0;
while ((input[i] >= '0' && input[i] <= '9') || input[i] == '.')
{
if (input[i] == '.')
{
i++;
inFraction = 1;
continue;
}
number = number * 10.0;
number = number + input[i] - '0';
i++;
if (inFraction) divider *= 10.0;
}
number /= divider;
printf("string %s -> number %g \n", input, number);
}
else
{
printf("Enter a number! \n");
}
}
Edit: As clux pointed out, this fails when the fraction starts with zeroes. Bummer. Anyway, perhaps someone conceives a simple fix? I can only think of adding a "readzeroes()" function and let that run after the dot.
You already have a function to read an int. Simply use that. Pseudo code:
float read_float()
{
float f = read_int()
if(next is dot) skipdot else return f;
float frac = read_int()
while (frac>1) frac /= 10
return f+frac;
}
Edit: only use this approach for small number of digits after the decimal point.
Read the comments to know why it would fail for a large number of digits.
Since you mentioned without using any library functions, you could do something like this.
float number;
int decimal = 0;
int decimal_found =10;
while(input[i]!='\0')
{
if((input[i] <='0' || input[i] >='9')&&input[i]!='.' )
break;
if(input[i] == '.')
decimal = 1;
if(decimal == 1)
{
number = number + (input[i] - '0')/decimal_found;
decimal_found = decimal_found*10;
}
else
{
number = number *10;
number = number + input[i] - '0';
}
i++;
}
Simply check a decimal variable to know when decimal has been reached, then use and if else to have separate conditions for the number variable
i'm newbie in C programming .
i have written this code for adding two numbers with 100 digits , but i don't know why the code does not work correctly , it suppose to move the carry but it doesn't .
and the other problem is its just ignoring the first digit (most significant digit) .
can anybody help me please ?
#include <stdio.h>
#include <ctype.h>
int sum[101] = {0};
int add(int a, int b);
void main()
{
static int a[100];
static int b[100];
char ch;
int i = 0;
int t;
for (t = 0; t != 100; ++t)
{
a[t] = 0;
}
for (t = 0; t != 100; ++t)
{
b[t] = 0;
}
do
{
ch = fgetc(stdin);
if ( isdigit(ch) )
{
a[i] = ch - 48;
++i;
}
else
break;
}
while (ch != '\n' || i == 100 || i != '\0');
i = 0;
do
{
ch = fgetc(stdin);
if ( isdigit(ch) )
{
b[i] = ch - 48;
++i;
}
else
break;
}
while (ch != '\n' || i == 100 || i != '\0');
for (;i!=0; --i)
{
add(a[i], b[i]);
}
for (i==0;i != 101; ++i)
{
printf("%d", sum[i]);
}
}
int add( int a , int b)
{
static int carry = 0;
float s = 0;
static int p = 101;
if (0 <= a+b+carry <= 9)
{
sum[p] = (a + b + carry);
carry = 0;
--p;
return 0;
}
else
{
if (10 <= a+b+carry < 20)
{
s = (((a+b+carry)/10.0 ) - 1) * 10 ;
carry = ((a+b+carry)/10.0) - (s/10);
}
else
{
s = (((a+b+carry)/10 ) - 2) * 10;
carry = ((a+b+carry)/10.0) - (s/10);
}
sum[p] = s;
--p;
return 0;
}
}
Your input loops have serious problem. Also you use i to count the length of both a and b, but you don't store the length of a. So if they type two numbers that are not equal length then you will get strange results.
The losing of the first digit is because of the loop:
for (;i!=0; --i)
This will execute for values i, i-1, i-2, ..., 1. It never executes with i == 0. The order of operations at the end of each iteration of a for loop is:
apply the third condition --i
test the second condition i != 0
if test succeeded, enter loop body
Here is some fixed up code:
int a_len;
for (a_len = 0; a_len != 100; ++a_len)
{
int ch = fgetc(stdin); // IMPORTANT: int, not char
if ( ch == '\n' || ch == EOF )
break;
a[a_len] = ch;
}
Similarly for b. In fact it would be a smart idea to make this code be a function, instead of copy-pasting it and changing a to b.
Once the input is complete, then you could write:
if ( a_len != b_len )
{
fprintf(stderr, "My program doesn't support numbers of different length yet\n");
exit(EXIT_FAILURE);
}
for (int i = a_len - 1; i >= 0; --i)
{
add(a[i], b[i]);
}
Moving onto the add function there are more serious problems here:
It's not even possible to hit the case of sum being 20
Do not use floating point, it introduces inaccuracies. Instead, doing s = a+b+carry - 10; carry = 1; achieves what you want.
You write out of bounds of sum: an array of size [101] has valid indices 0 through 100. But p starts at 101.
NB. The way that large-number code normally tackles the problems of different size input, and some other problems, is to have a[0] be the least-significant digit; then you can just expand into the unused places as far as you need to go when you are adding or multiplying.