While I was making a dictionary using C it showed me the meaning of the word which is not present in the dictionary itself. I checked the function for checking the equality of two strings and its working fine but when I implement that function in the lookup function of the dictionary where it searches for the word shows me the meaning of the word it is not working as I intended it to do. I am not looking for a good performance I was just revising my basics in the function and simple boolean functions.
Here is the Code:
struct Entry
{
char word[50];
char defination[500];
};
bool isEqualString(const char str1[], const char str2[])
{
bool flag = true;
int i;
for(i = 0; str1[i] != '\0'; i++)
if (str1[i] == str2[i])
{
flag = true;
}
if ((str1[i] == str2[i]) && str1[i] == '\0')
flag = true;
else
flag = false;
return flag;
}
int Lookup(const struct Entry dictionary[], const char search[], int entries)
{
int i;
bool isEqualString(const char str1[], const char str2[]);
for (i = 0; i < entries; i++)
{
if (isEqualString(search, dictionary[i].word))
{
printf("%d and its indice = %d\n", isEqualString(search, dictionary[i].word), i);
return i;
}
}
return -1;
}
void main()
{
struct Entry dictionary[2] =
{ {"Hello", "It means hi."},
{"Dead", "It means you are dead"} };
int Lookup(const struct Entry dictionary[], const char search[], int entries);
int entries = 2, searchEntry;
char searchWord[10];
printf("Give us a word to find in the dictionary: \n");
scanf("%s", searchWord);
searchEntry = Lookup(dictionary, searchWord, entries);
if (searchEntry != (-1))
printf("\n%s %s", dictionary[searchEntry].word, dictionary[searchEntry].defination);
}
the logic in this function:
bool isEqualString(const char str1[], const char str2[])
is not quite right.
Suggest:
#include <stdbool.h>
#include <string.h>
bool isEqualString(const char str1[], const char str2[])
{
bool flag = true;
for( size_t i = 0; i < (strlen(str1)+1); i++ )
{
if ( str1[i] != str2[i] )
{
flag = false;
break;
}
}
return flag;
}
Related
I'm writing a program that implements the Alberti Cipher, and when testing, the final print always gives a string of jargon before the actual encryption. Right now its printing \x80\x16G\xbf\xfe\x7fKHOORZRUOG, with KHOOR..... being the actual encryption. Any help appreciated :)
#include <stdio.h>
#include <stdlib.h>
int letterToNumber(char letter){
char str[2] = { letter };
int num = strtol( str, NULL, 36 ) - 10;
return num;
}
int getSize (const char * s) {
const char * t;
int size = 0;
for (t = s; *t != '\0'; t++) {
size++;
}
return size;
}
char numToChar(int numInp){
numInp=numInp+65;
char returnChar=(char)numInp;
return returnChar;
}
void encrypt_alberti(const char *message,const char *inner_ring, int initialShift,int periodicShift,int periodLength,char **result){
//sets initial shift
int numArray[25];
int count=0;
int shiftCount=0;
for(int i = 0; i < 26; ++i) {
numArray[i]=(i+initialShift)%26;
}
//encrypts each character and prints
int messageSize=getSize(message);
char encryptedMessage[messageSize];
for(int i=0; i<messageSize;i++){
count++;
if(periodicShift!=0){
if(count%periodicShift==0){
shiftCount++;
}
}
else{
periodLength=0;
}
char toBeEncrypted=message[i];
int charNumber=letterToNumber(toBeEncrypted);
int encryptedNum=numArray[(charNumber+(shiftCount*periodLength))%26];
char encryptedChar=numToChar(encryptedNum);
strncat(encryptedMessage, &encryptedChar, 1);
}
char* p1=malloc(sizeof(encryptedMessage));
strcpy(p1,encryptedMessage);
*result=p1;
}
void main(void) {
const char *example_message = "HELLOWORLD";
const char *example_inner = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *encrypted_message = NULL;
encrypt_alberti(example_message, example_inner, 3, 0, 1, &encrypted_message);
printf("message is %s\n", encrypted_message);
printf("-----------------");
free(encrypted_message);
}
}
I have an assignment for checking if some input words are from a dictionary and print and count the ones that are not. Initially the dictionary was an array and I had to change it to a trie to make it faster (the code that is between /* */ is the changed code). After trying to compile it I get this weird
I have no idea what to do now. The files and code that I used are the following:
dictionary.h:
// declares a dictionary
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include <stdbool.h>
// maximum length for a word
#define LENGTH 45
//Nr of possible children=size of the alphabet
#define N 26
//a trie as dictionary
typedef struct dict
{
bool is_word;
struct dict *children[N];
} dict;
// a dictionary is an array
/* typedef struct dict {
int numWords;
int maxWords;
char **words;
} dict;
*/
dict *newEmptyDict();
void addWord(char word[LENGTH + 1], dict *d);
bool check(const char *word, dict *d);
void freeDict(dict *n);
#endif // DICTIONARY_H
dictionary.c:
// implements a dictionary
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dictionary.h"
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
/* dict *newEmptyDict() {
dict *d = malloc(sizeof(dict));
if (d == NULL) {
return NULL;
}
d->numWords = 0;
d->maxWords = 1;
d->words = malloc(sizeof(char*) * d->maxWords);
return d;
}
*/
//create an empty trie dictionary
dict *newEmptyDict() {
dict *pN = NULL;
pN=(dict*)malloc(sizeof(dict));
if (pN){
int i;
pN->is_word=false;
for (i=0;i<=N;i++)
pN->children[i]=NULL;
}
return pN;
}
// add word to the dictionary if it is is not already known
/* void addWord(char word[LENGTH + 1], dict *d) {
if (!check(word, d)) {
// if we need more space before adding the word, double the size
if (d->numWords == d->maxWords) {
d->words = realloc(d->words,(sizeof(char*)) * (d->maxWords * 2));
if (d->words == NULL) {
printf("Out of memory.\n");
exit(-1);
}
d->maxWords = d->maxWords * 2;
}
// now we actually add the word
d->words[d->numWords] = malloc(sizeof(char) * (LENGTH + 1));
strcpy(d->words[d->numWords],word);
d->numWords++;
}
} */
void addWord(char word[LENGTH + 1], dict *d) {
int level;
int len=strlen(word);
int index;
dict *pC = d;
for (level=0;level<len;level++){
index = CHAR_TO_INDEX(word[level]);
if(!pC->children[index])
pC->children[index] = newEmptyDict();
pC=pC->children[index];
}
pC->is_word = true;
}
// check whether word is in dictionary
/* bool check(const char *word, dict *d) {
for (int i = 0; i < d->numWords; i++) {
if (strcmp(d->words[i],word) == 0) {
return true;
}
}
return false;
} */
bool check(const char *word, dict *d) {
int level;
int len=strlen(word);
int index;
dict *pC = d;
for (level=0;level<len;level++){
index = CHAR_TO_INDEX(word[level]);
if (!pC->children[index])
return false;
pC=pC->children[index];
}
return (pC!=NULL && pC->is_word);
}
/* void freeDict(dict *d) {
for (int i = 0; i < d->numWords; i++) {
free(d->words[i]);
}
free(d->words);
free(d);
}
*/
void freeDict(dict *d) {
int i;
for (i=0;i<=N;i++)
if (d->children[i]) freeDict(d->children[i]);
free (d);
}
speller.c:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "dictionary.h"
// remove non-alphabetic characters and convert to lower case
void trimWord(char *word) {
int k = 0;
for (int i = 0; i < (int) strlen(word); i++) {
if (isalpha(word[i])) {
word[k] = tolower(word[i]);
k++;
}
}
word[k] = '\0';
}
int main(int argc, char *argv[]) {
char word[LENGTH + 1] = "";
// step 1: read in the dictionary
dict *dictionary = newEmptyDict();
while (scanf("%45s",word) && word[0] != '!') {
trimWord(word);
addWord(word,dictionary);
memset(word,0,strlen(word));
}
// step 2: read in text
int counter = 0; // number of unknown words
// BUG: This loop is wrong. It will read "one,twwo" as one word "onetwwo".
/* while (scanf("%45s", word) != EOF) {
trimWord(word);
if (!check(word,dictionary)) {
counter++;
printf("%s\n",word);
}
}
*/
int index = 0; int wcheck=0; //wcheck is for knowing if a word has begun so no unnecesary \n's are printed
int c = EOF;
while ((c = getchar()) && c != EOF) {
if (isalpha(c)){
word[index]=c;
index++;
wcheck=1;
}else if (wcheck){
trimWord(word);
if(!check(word,dictionary)){
counter++;
printf("%s\n", word);
}
memset(word,0,strlen(word));
index=0;
wcheck=0;
}
}
// TODO: Replace the above while loop with a correct solution.
// Hints:
// - you should read one character at a time, using getchar()
// - alphabetical characters should be appended to the current word
// - any other symbol should terminate the word
// this code might be useful:
/*
int index = 0;
int c = EOF;
while ((c = getchar()) && c != EOF) {
// ...
}
*/
// step 3: print number of unknown words
printf("%d\n", counter);
freeDict(dictionary);
return 0;
}
Could you help please? I believe it has something to do with allocation but I'm still stuck. Thank you!
I got this part of a C program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void){
char *mRNA = spleissen("AUAGUAAAAGCUCUGUUUAGGAGA", "GU", "AG");
printf("mRNA: %s\n", mRNA);
free(mRNA);
return 0;
}
I have to write the function spleissen which should work like this: it cuts out a string which goes from a GU to an AG and everything in between those two. So the program output is:
mRNA: AUACUCUGAGA
I don't really know how I can cut those parts out.
I am not allowed to use includes other than stdio, string and stdlib.
char *spleissen(const char *src, const char *start, const char *end){
size_t len = strlen(src);
char *s, *e, *ret, *work;
ret = work = malloc(len + 1);
strcpy(work, src);
len = strlen(end);
while(s = strstr(work, start)){
if((e = strstr(s, end))==NULL)
break;//delete upto last?
memmove(s, e + len, strlen(e+len)+1);
work = s;
}
return ret;
}
I think you can simply do this:
char *spleissen(char *array, char *G, char *A)
{
int l=strlen(array);
int i, j=0;
char returnstr[10010];
int b=0;
for(i=0; i<l; i++)
{
if(G[0]==array[i] && G[1]==array[i+1])
{
b=1, i++;
continue;
}
else if(A[0]==array[i] && A[1]==array[i+1] && b==1)
{
b=0, i++;
continue;
}
if(b==0)
{
returnstr[j]=array[i];
j++;
}
}
return returnstr;
}
So I have a file containing lets say:
cat
dog
cat
I am trying to go through the file, have it recognize there are two cat elements and one dog element, and then have in the same file edited as:
cat - 2
dog - 1
I already have all the words saved in an array of strings, char **wordList, and I am trying to sort them with qsort and then put it in the format as described above. My qsort functions are:
stringcmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
}
void wordSort(char **wordlist)
{
size_t strings_len = numwords - 1;
qsort(wordlist, strings_len, sizeof(char*), stringcmp);
wordFile(wordlist);
}
void wordFile(char **wordlist)
{
if((outFilePtr2 = fopen(outWords, "w")) != NULL)
{
for(x = 1; x < numwords; x++)
{
fputs(wordlist[x], outFilePtr2);
fputs("\n", outFilePtr2);
}
fclose(outFilePtr2);
}
else
{
printf("File\"%s\" could not be opened.\n", outWords);
}
}
It is not sorting anything in order though. How do I fix it?
The following program works with your definition of stringcmp (which seems correct):
int main (int argc, char *argv[]) {
int i;
qsort(argv, argc, sizeof(char *), &stringcmp);
for (i = 0; i != argc; i++) printf("%s\n", argv[i]);
}
Thus I suspect that you have a problem with the definition of char **wordList.
UPDATE
This version slightly modified/completed version of your program works for me:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *outWords = "outWords.txt";
char *wordList[] = { "cat", "dog", "cat" };
#define numwords (sizeof(wordList) / sizeof(wordList[0]))
FILE *outFilePtr2;
int x;
int stringcmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
}
void wordSort(char **wordlist)
{
qsort(wordlist, numwords, sizeof(char*), stringcmp);
wordFile(wordlist);
}
void wordFile(char **wordlist)
{
if((outFilePtr2 = fopen(outWords, "w")) != NULL)
{
for(x = 0; x < numwords; x++)
{
fputs(wordlist[x], outFilePtr2);
fputs("\n", outFilePtr2);
}
fclose(outFilePtr2);
}
else
{
printf("File\"%s\" could not be opened.\n", outWords);
}
}
int main() {
wordSort(wordList);
wordFile(wordList);
return 0;
}
I adapted the second argument of qsort (else the last string pointer would not be considered, and left unchanged). I also adapted the initialization x=0 of the for-loop in wordFile for the first string to be printed, too.
You may have defined **wordList in some other way causing a problem, you did not provide the code for it.
Alright sorry for creating another question but the last one got overwhelmed and chaotic.
So I'm making a hash table which inserts words from a file (tokens) and after I have inserted them I need to sort them. The program template was given, the only functions that weren't complete were : insert_ht() , clear_ht() and compare. Even though I've done tons of search about qsort with compare, the program doesn't sort the frequencies (number of times each word was inserted) . I want em sorted from the highest to lowest.
Here is the code : "note that i shouldn't change any function except insert_ht() , clear_ht() and compare
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
struct node *new_list;
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
new_list = malloc(sizeof(link));
new_list->token = strdup(token) ;
new_list->freq = 1;
new_list->next = htable[hashval];
htable[hashval] = new_list;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
void clear_ht()
{
int i;
for(i=0; i<HTABLE_SIZ; i++) {
while(htable[i]->token!=NULL) {
htable[i]->token=NULL;
htable[i]->freq=NULL;
free(htable[i]);
}
}
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if (p1->freq > p2->freq)
return(+1);
else if (p1->freq < p2->freq)
return(-1);
else
return(0);
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}