number characters from input - c

bool in_array(char a[], char input, int len){
for (int l = 0; l < len; l++){
}
}
return false;
}
int main(void) {
char i = 'l';
int count = 0;
int count_d = 0;
char a[1000] = {0};
else{
count_d++;
}
}
printf("%d\n", count_d);
}
this is the code i have but this returns numbers of times it has duplicated
as there are two characters a and b

If you have learnt only arrays and do not know how to allocate memory dynamically then use a second array to store unique duplicated characters.
Here is a demonstrative program.
#include <stdio.h>
#include <stdbool.h>
bool in_array( const char a[], size_t n, char c )
{
size_t i = 0;
while ( i != n && a[i] != c ) i++;
return i != n;
}
int main(void)
{
enum { N = 128 };
char a[N];
char b[N / 2];
size_t count_duplicates = 0;
size_t count = 0;
char c;
while ( count < N && scanf( " %c", &c ) == 1 )
{
if ( !in_array( a, count, c ) )
{
a[count++] = c;
}
else if ( !in_array( b, count_duplicates, c ) )
{
b[count_duplicates++] = c;
}
}
printf( "There are %zu duplicated character(s).\n", count_duplicates );
return 0;
}
If to enter the sequence of characters
aaabbaaac
then the program output will be
There are 2 duplicated character(s).

i hope it will help you :
`#include <unistd.h>
#include <stdio.h>
#include <string.h>
int in_a(char *a, char c)
{
for (int i = 0; i < strlen(a); i++)
if (a[i] == c)
return 0;
return (1);
}
int main(int ac, char **av)
{
int count_duplicates = 0;
int same = 0;
char old = 0;
char new[128] = {0}; // i
int count = 0;
char *a = av[1];
while (a[count] != '\0') {
if (old != a[count] && in_a(new, a[count])) {
same = 0;
}
if (a[count] == old && same != 1) {
count_duplicates += 1;
same = 1;
}
old = a[count];
new[count] = a[count];
count += 1;
}
printf("%i\n", count_duplicates);
return (0);
}`

Related

C exercise return information about first position

exercise in C:
write a function 'any' wchich returns information about position of first occurrence in s1 any lsign from s2. Return -1 when s1 doesnt includes signs from s2.
And my code is:
#include <stdio.h>
#include <stdlib.h>
int any(char s1[], char s2[]) {
int i, j;
int koniec;
for (i = 0; s2[i] != '\0'; i++) {
for (j = 0; s1[j] != '\0'; j++) {
if (s1[j] == s2[i]) {
koniec = j;
}
else
{
koniec = -1;
}
}
}
return koniec;
}
int main()
{
char w1[] = "Dominik";
char w2[] = "zcki";
int wynik;
wynik = any(w1, w2);
printf("%d", wynik);
return 0;
}
but it returns: -1
but should 3
what is wrong?
Just return the position when you find it and do not keep looping:
int any(char s1[], char s2[]) {
int i, j;
for (i = 0; s1[i] != '\0'; i++) {
for (j = 0; s2[j] != '\0'; j++) {
if (s1[i] == s2[j]) {
return j;
}
}
}
return -1;
}
The if statement within the inner loop
if (s1[j] == s2[i]) {
koniec = j;
}
else
{
koniec = -1;
}
Does not make a sense because the value of the variable koniec will be overwritten in the last iterations of the both loops.
Moreover due to the order of the loops you are searching in fact a character from the string s2 in the string s1 while you need to find the first character in s1 that is present in s2.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stddef.h>
ptrdiff_t any( const char *s1, const char *s2 )
{
ptrdiff_t pos = -1;
for ( const char *p1 = s1; pos == -1 && *p1; ++p1 )
{
const char *p2 = s2;
while ( *p2 && *p2 != *p1 ) ++ p2;
if ( *p2 ) pos = p1 - s1;
}
return pos;
}
int main(void)
{
char w1[] = "Dominik";
char w2[] = "zcki";
printf( "%td\n", any( w1, w2 ) );
return 0;
}
The program output is
3
Indeed the first character from w1 that is present in w2 is the character 'i'. Pay attention to that positions start from 0.
#include <stdio.h>
#include <stdlib.h>
int any(char *s1, char *s2)
{
int koniec=0;
int j=0;
for (int i = 0; s1[i]!='\0'; i++)
{j=0;
while(s1[i]!=s2[j]&&s2[j]!='\0')
{
j++;
}
if(s2[j]!='\0')
{
return j;
}
}
return -1;
}
int main()
{
char w1[] = "Dominik";
char w2[] = "zcki";
printf("%d\n", any(w1, w2));
return 0;
}

Iterate Over Char Array Elements in C

This code is supposed to take a user's input and convert it to binary. The input is grouped into an integer array to store character codes and/or adjacent digits, then each item in the integer array is converted to binary. When the user types "c357", "c" should be converted to 99, then converted to binary. Then, "357" should be converted to binary as well. In the main() function, strlen(convert) does not accurately represent the number of items in array convert, thus only iterating over the first array item.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#define EIGHT_BITS 255
#define SIXTEEN_BITS 65535
#define THIRTY_TWO_BITS 4294967295UL
// DETERMINE NUMBER OF BITS TO OUTPUT
int getBitLength(unsigned long d) {
int l;
if (d <= EIGHT_BITS) {
l = 8;
}
else if (d > EIGHT_BITS && d <= SIXTEEN_BITS) {
l = 16;
}
else if (d > SIXTEEN_BITS && d <= THIRTY_TWO_BITS) {
l = 32;
}
return l;
}
// CONVERT INPUT TO BINARY VALUE
char* convertToBinary(unsigned long int decimal) {
int l = getBitLength(decimal);
static char b[33];
char bin[33];
int i, j, k = 0, r;
b[33] = '\0';
bin[33] = '\0';
printf("Bits................ %ld\n", l);
// creates array
for (i = 0; i < l; i++) {
r = decimal % 2;
decimal /= 2;
b[i] = r;
}
// reverses array for binary value
for (j = l - 1; j >= 0; j--) {
bin[k] = b[j];
strncpy(&bin[k], &b[j], l);
snprintf(&bin[k], l, "%d", b[j]);
k++;
}
printf("Binary Value: %s\n", bin);
return bin;
}
unsigned long int* numbersToConvert(char* input) {
const int MAX_INPUT = 20;
int i, k = 0, z = 0;
char numbers[MAX_INPUT];
unsigned long int *toConvert = malloc(MAX_INPUT * sizeof(int));
numbers[MAX_INPUT] = '\0';
for (i = 0; i < strlen(input); i++) {
if (isdigit(input[i])) {
numbers[z] = input[i];
if (!isdigit(input[i + 1])) {
toConvert[k] = strtol(numbers, NULL, 10);
printf("----- %ld -----\n", toConvert[k]);
z = 0;
}
else {
z++;
}
}
else {
printf("----- %c -----\n", input[i]);
printf("Character Code: %d\n", input[i]);
toConvert[k] = (unsigned long int) input[i];
}
k++;
}
return toConvert;
}
int main(void) {
const int MAX_INPUT = 20;
int i, p;
char input[MAX_INPUT];
unsigned long int* convert;
printf("------- Input --------\n");
scanf("%s", input);
input[MAX_INPUT] = '\0';
// PRINT INPUT AND SIZE
printf("\nInput: %s\n", input);
convert = numbersToConvert(input);
convert[MAX_INPUT] = '\0';
printf("strlen: %ld\n", strlen(convert));
for (i = 0; i < strlen(convert); i++) {
printf("num array: %ld\n", convert[i]);
convertToBinary(convert[i]);
}
return 0;
}
I have attempted to null terminate each string to prevent undefined behavior. I am unsure if certain variables, if any, are meant to be static.
It is hard to read your code.
Here you have something working (converting the number to binary):
static char *reverse(char *str)
{
char *end = str + strlen(str) - 1;
char *saved = str;
int ch;
while(end > str)
{
ch = *end;
*end-- = *str;
*str++ = ch;
}
return saved;
}
char *tostr(char *buff, unsigned long long val)
{
if(buff)
{
char *cpos = buff;
while(val)
{
*cpos++ = (val & 1) + '0';
val >>= 1;
}
*cpos = 0;
reverse(buff);
}
return buff;
}
int main()
{
char buff[128];
printf("%s\n", tostr(buff, 128));
}
https://godbolt.org/z/6sRC4C

Functions fopen/calloc/malloc and and ways of their replacement

I want to make a simple program (but difficult for me), which will find contacts by letters (parts of the name are entered using numbers) and by numbers (parts of the number). Input - numbers, from the standard input (txt file), output - contacts that contain these numbers (letters). The contact file looks like
(name)
(number)
(name)
(…)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (32)
/*
IN :
contacts.txt :
Sad Mirrow
38074025
Deniel Kovalski
78032596
Miky Trance
88055535
Martin Worried
77432651
96 [key number from standard entry]
OUT:
Deniel Kovalski
[because 96 matches in his number]
Martin Worried
[96 matches in his name Wo]
*/
typedef struct Contact {
char* name;
char* number;
} Contact;
char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
bool find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return true;
}
return false;
}
bool matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return true;
}
return false;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
size_t arrSize = 32;
Contact* contacts = malloc(arrSize * sizeof(Contact));
int k = 0;
size_t nameSize = MAX_NAME;
size_t numSize = MAX_NUM;
char *nameBuf = malloc(MAX_NAME);
char *numBuf = malloc(MAX_NUM);
FILE* f = fopen("contacts.txt", "r");
while (fgets(nameBuf, nameSize, f)
&& fgets(numBuf, numSize, f)){
contacts[k].name = malloc(MAX_NAME);
contacts[k].number = malloc(MAX_NUM);
strcpy(contacts[k].name, nameBuf);
strcpy(contacts[k].number, numBuf);
k++;
if (k == arrSize);
arrSize <<= 1;
contacts = realloc(contacts, arrSize * sizeof(Contact));
}
for (int i = 0; i < k; i++){
bool matchesName = matches(contacts[i].name, key);
bool matchesNumber = matches(contacts[i].number, key);
if (matchesName || matchesNumber)
printf("%s\n", contacts[i].name);
}
for (int i = 0; i < k; i++){
free(contacts[i].name);
free(contacts[i].number);
}
free(contacts);
free(nameBuf);
free(numBuf);
fclose(f);
return 0;
}
At first we did as we could. Then was a time to fulfill the conditions of the task and the problem came. It needs to be done without malloc/calloc/fopen. I tried to fix everything, but I ran into a problem that the program does not work and it seems to me that I'm confused.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (64)
struct Folio
{
char name[1000];
char num[1000];
};
static char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
int find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return 1;
}
return 0;
}
int matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
unsigned int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return 1;
}
return 0;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
struct Folio contacts[42]; //Entry entries[42]
int contacts_count = 0; //entries_count = 0;
//FILE* f = fopen("seznam.txt", "r");
char name[1000];
char num[1000]; //number[1000]
while (fgets(name, MAX_NAME, stdin) != NULL && fgets(num, MAX_NUM, stdin) != NULL)
{
// copy to struct
strcpy(contacts[contacts_count].name, name);
strcpy(contacts[contacts_count].num, num);
contacts_count++;
}
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[contacts_count].name, contacts[contacts_count].num);
}
//fclose(f);
return 0;
}
I want to ask the help of experienced programmers.
matchTable[10][9] is too small to save "7pqrsPQRS" as a string as needed in matchTable[j][i] != '\0';. Needs 10.
Suggest
//static char matchTable[10][9] = {
// "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
// "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
//};
static char *matchTable[10] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
Perhaps other issues too.
I believe the main issue is the the search logic. Code loops over all contacts, but will attempt a match against the a non-existing contacts entry.
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
...
Should this use the i-th contacts ?
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[i].name, key);
int matchesNumber = matches(contacts[i].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[i].name, contacts[contacts_count].num);
}
Or even
for (int i = 0; i < contacts_count; i++){
struct Folio con_p = &contacts[i] ;
int matchesName = matches(con_p->name, key);
int matchesNumber = matches(con_p->num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", con_p->name, con_p->num);
}
Also take a look at answer from chux - Reinstate Monica

Caesar Cipher not returning correct key

So my decrypter program seems to not be able to find the key and implement it by itself. I noticed that if I changed the key to equal -5 which is the correct key it would print out the decrypted text correctly. However I am unable to figure out how to make the program figure it out by itself without having me to put it in manually. Any help would be greatly appreciated! Thank you!
rotUtils.h
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "rotUtils.h"
int rotate(int c, int n){
if (n == 0) return c;
int nRot = abs(n) % (RANGECHAR + 1);
if(n > 0)
return rotatePlus(c + nRot);
else
return rotateMinus(c - nRot);
}
int rotatePlus(int sum){
int diff = sum - MAXCHAR;
if (sum > MAXCHAR) sum = MINCHAR + diff - 1;
return sum;
}
int rotateMinus(int sum){
int diff = MINCHAR - sum;
if (sum < MINCHAR) sum = MAXCHAR - diff + 1;
return sum;
}
decrypt.cpp
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "rotUtils.h"
bool solved( char decodearr[], char dictarr[][30], int size1, int size2){
char* compared;
bool result = false;
for(int j = 0; j < size2; j++){
compared = strstr( decodearr, dictarr[j]);
}
if( compared != '\0'){
result = true;
}
return result;
}
int decode( char codearr[], char dictarr[][30], int size1, int size2)
{
bool solution = false;
int key = -50; This is where I had to change it to -5 to solve
char decodearr[10000];
while(solution == false && key < 51)
{
for( int i = 0; i < size1; i++)
{
if(!isspace(codearr[i]))
{
decodearr[i] = rotate(codearr[i], key);
}
else
decodearr[i] = codearr[i];
}
solution = solved( decodearr, dictarr, size1, size2);
if( solution == false)
{
key++;
}
}
for( int j = 0; j < size1; j++)
{
codearr[j] = decodearr[j];
}
return key;
}
int main( int argc, char* argv[])
{
char* file = argv[1];
char* dictionary = argv[2];
char code[10000];
char dict[30000][30];
FILE* codeFile;
codeFile = fopen(file, "r");
int i = 0;
int j = 0;
int key;
FILE* dictFile;
dictFile = fopen(dictionary, "r");
while(!feof(codeFile))
{
code[i] = fgetc(codeFile);
i++;
}
code[ i ]= '\0';
fclose(codeFile);
while(!feof(dictFile))
{
fscanf(dictFile, "%s", dict[j]);
j++;
}
key = decode(code, dict, i, j);
fclose(dictFile);
for(int k = 0; k < i; k++)
{
printf("%c", code[k]);
}
printf( "\nThe key is: %d\n", key);
return 0;
}
Solved() will only return true if there is a match on the last dictionary word currently, you have to move that check inside. You could print to screen whenever you find a key that has a match on your dictionary and/or keep a list of possible keys then print after you are done with them all, right now you would exit as soon as you find any match even if it was just luck.

Loop with simple counter malfunctioning?

I have a program that takes a char array and calls the function convert. The function determines whether the character is a letter or number. The program is supposed to output the first letter it finds in the string. and the first numbers it finds in the string. My loop to stop looking for letters after it finds one isn't working.
Any thoughts?
Code is written in C using the Borland Compiler.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char **);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
if(c >= 1){
*charptr = &array[i];
c++;
}
else
break;
}
else if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
}
return x;
}
UPDATE:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char ** charptr);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c;
char b[512];
for (i=0;array[i] != 0;i++){
if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
else if (isalpha(array[i]))
{
c++;
if(c >= 1){
*charptr = &array[i];
}
}
}
return x;
}
You have a logic error. c is initialized to 0. There is a line to increment c but it is inside an if block that will never be true.
if(c >= 1){
*charptr = &array[i];
c++;
}
Catch 22???
Perhaps you meant to use:
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
// No need for checking the value of c
// return as soon you find an alphabet.
*charptr = &array[i];
break;
}
else if ( isdigit(array[i]))
// If you are looking for an alphabet only,
// why do you have this block of code???
x = 10*x + array[i] - '0';
}
return x;
}
Update
Perhaps, this is what you are looking for.
int convert (char array[], char ** charptr)
{
size_t i;
int x = 0;
size_t len = strlen(array);
// Set charptr to NULL in case there are no letters in the input.
*charptr = NULL;
for (i=0;i<len;i++){
if ( isalpha(array[i]))
{
*charptr = &array[i];
return x;
}
else if ( isdigit(array[i]))
{
x = 10*x + array[i] - '0';
}
}
return x;
}
int scanString(char array[],char * charptr)
{
int len = strlen(array);
int digs = 0;
int x = 0;
*charptr = 0;
for (int i=0;i<len;i++){
if (charptr == 0 && isalpha(array[i]))
{
*charptr = array[i];
}
else if (digs == 0 && isdigit(array[i])){
x = array[i] - '0';
digs = 1;
}
if(digs > 0 && charptr != 0)
break;
}
return x;
}
the spec says return the first character found so changed the charptr.

Resources