Array not giving back letters the user entered - c

int read_word(char word[], int max_size_word) {
{
int c = 0, let_count = 0;
printf("\nPlease enter your word: ");
char input = toupper(getchar());
for(c = 1; c < 7; c++) {
if(input != '\n') {
word[c] = input;
let_count++;
} else if(input == '\n')
input = toupper(getchar()); //The word the user entered is in word[c]
}
return let_count;
}
}
int check_word(char word[], int size_word, int letter_set[], int
size_letter_set, int arr[])
{
char word_copy;
for(int ii = 0; ii < 7; ii++) {
word_copy = word[ii];
}
printf("The word is %c\n" , word_copy);
return 0;
}
I'm programming a game of scrabble. Here are the two functions that pertain to my question. Basically I want to check if my read word function works. Thats what the bottom printf does. However when I enter a couple letters my "The word is...." printf only gives back the first letter entered. I want the printf to give back every letter entered. Any help would be appreciated!

You're only printing one letter because in printf("The word is %c\n" , word_copy); your word_copy is a char and not a string.
In check_word, try replacing
char word_copy;
for(int ii = 0; ii < 7; ii++) {
word_copy = word[ii];
}
printf("The word is %c\n" , word_copy);
return 0;
by
int word_size = strlen(word); //calculate the length of your word
char word_copy[word_size + 1]; //create copy string with word size +1 for \0
int ii = 0;
for(ii; ii < 7; ii++) { //I set ii < 7 to do like you but... Why did you set 7?
word_copy[ii] = word[ii]; //put the characters of your word into the copy string
}
word_copy[ii] = '\0'; //end the string puttin a \0 at its end
printf("The word is %s\n" , word_copy); //here i replace %c (char) by %s (string)
return 0;
There are similar problems in your read_word function, you should be able to fix them if you understand the fixes I made in your check_word function (even if you can just put your printf in the for loop i think that doing it like so can help you understand the problem in read_word).

Related

Why does my C code say char matches other char even tho it does?

I am making a simple hangman game in C, I am trying to check if each character in the string matches the guessed character. but when I test it, it gives results that are incorrect and shouldn't have passed the if statement in the first place. for example when I enter the letter a (The word is apple) it give me a__a. somehow the word became 4 letters long instead of 5 and it said that the last letter is a even tho it isn't.
https://imgur.com/a/DZDTbbj
#include <stdio.h>
int main() {
int size = 0;
char word[] = "apple", guess, hidden[size];
while (word[size] != '\0') {
size++;
}
for (int i = 0; i < size; ++i) {
hidden[i] = '_';
}
while (1) {
printf("%s\n", hidden);
scanf(" %c", &guess);
for (int y = 0; y < size; ++y) {
if (word[y] == guess) {
hidden[y] = guess;
}
}
}
return 0;
}
You declare hidden[size] before the loop that sets size to the length of word. So it's using the initial value 0 as the length of the array.
Move that declaration down to after the loop. Also, you need to make the length size+1 to allow room for the null terminator, and then add the null terminator.
int main()
{
int size=0;
char word[]="apple",guess;
while(word[size]!='\0'){
size++;
}
char hidden[size+1];
for (int i = 0; i < size; ++i)
{
hidden[i]='_';
}
hidden[size] = '\0';
while(1){
printf("%s\n",hidden );
scanf(" %c",&guess);
for (int y = 0; y < size; ++y)
{
if (word[y] == guess)
{
hidden[y]=guess;
}
}
}
return 0;
}

comparing a char to a string in C

I'm quite new to C and I'm wondering why in the code below, the char I'm comparing to each letter of the string word is showing that it's equal everytime.
For example
If I've inputted the word
apple
and I'm looking for any repeating char in "apple" my function. I pass in to the function each char of apple such as a, p, p etc. It should return 1 when I pass in p since it's repeated, but instead, for every char of apple, my function says a == word[0], a == word[1] even though word[1] for "apple" is 'p'.
I know char is ASCII, so each char has a number value, but I'm not sure why this is not working. Perhaps, I'm using the pointer *word in the functions arguments incorrectly?
My code is below for my function, rpt_letter:
int rpt_letter(char *word, char c)
{
int i;
int count = 0;
i = 0;
printf("This is the WORD %s\n", word);
while(count < 2)
{
if(word[i] == c)
{
count++;
printf("the count is %d\n the char is %c and the string is %c\n", count, c, word[i]);
}
i++;
}
if (count<2)
{
// printf("letter %c was not found in the array. \n", c);
return 0;
}
else
{
//printf("letter %c was found at index %d in the array.\n", c, mid);
repeats[rpt_counter] = c;
rpt_counter++;
return 1;
}
return 0;
}
I'll include the main method just in case -- but I believe the main method is working well
int main(void)
{
//! showArray(list, cursors=[ia, ib, mid])
//int n = 51;
char word[51];
scanf("%s", word);
//length of string
for (n=0; word[n] != '\0'; n++); //calculate length of String
printf("Length of the string: %i\n", n);
int count = 0;
//sort words
int i;
char swap = ' ';
for(int k = 0; k < n; k++)
{
for (i=0; i<n-1; i++)
{
//if prev char bigger then next char
if (word[i] > word[i+1])
{
//make swap = prev char
swap = word[i];
//switch prev char with next char
word[i] = word[i+1];
//make next letter char
word[i+1] = swap;
}
}
}
printf("%s\n", word);
for (i=0; i<n-1; i++)
{
int rpt = rpt_letter(word, word[i]);
if(rpt == 1)
{
count++;
}
}
printf("%d", count);
return 0;
}
I've tried a number of things such as using the operator !=, also <, > but it gives me the same result that each word[ia] == c.
You are getting this issue because in your code rpt_letter() the while loop has a terminating condition count >= 2. Now consider input apple and character a. As a appears in apple only once, the count after traversing the whole word remains 1. But the loop doesn't terminate. So, the index i becomes greater than the length of string and tries to check the character appearing after that.
The loop terminates eventually when it gets another a this way. You need to add a check for the terminating null character in your loop so that it doesn't cross the length of the string .
Change the while loop condition to something like -
while((count < 2) && (word[i] != '\0'))

C Program Printing Duplicate Char

I'm trying to make a program in C that reads a word and prints if there are any duplicates and if so the number of occurrences. It works (as you can see in the attached pic) but once a letter has been printed I don't want it to reprint the same letter.
I've tried storing the duplicate chars in an array and then comparing the new duplicate to the duplicate array but it doesn't seem to be working.
Anyone know a simple way to not reprint?
#include <stdio.h>
#include <string.h>
int main(void) {
char word[100];
int x, i, j, freq, duplicates;
printf("Enter a word>\n");
scanf("%s", word);
x = strlen(word);
duplicates = 0;
freq = 1;
for(; i < x; i++) {
j = 0;
for(; j < x; j++) {
if ((word[i] == word[j]) && (i != j)) {
freq = freq + 1;
}
}
if (freq >= 2) {
printf("Duplicate letter: %c, Occurences: %d\n", word[i], freq);
duplicates = 1;
freq = 1;
}
}
if (duplicates < 1) {
printf("No duplicates found\n");
}
return 0;
}
Your problem here is in fors that look for the duplicate letter
The first one should go throw the string to look for all letters:
for (i = 0; i < x; i++) {
The second should look for the occurrence of the same character:
for (j = i; j < x; j++) {
Its because it runs once on each time it finds t and e respectively. One solution would be to find all occurrences of that char in the char array after printing the duplicate notification and removing it.
char * removeLetterFromArray(int toBeRemoved, char* string, int stringLength){
char * newString = malloc(stringLength * sizeof(char));
for(int i = 0; i < toBeRemoved; i++){
newString[i] = string[i];
}
for(int i = toBeRemoved; i < stringLength; i++){
newString[i] = string[i + 1];
}
return newString;
}
that code should remove the letter that you define the index of with toBeRemoved
So after you find a letter that has a duplicate loop through the code to find all places that letter occurs and pass them indexs to the above method.
If you do not wish to use the above method another option would be to create an array of letters that have already been output and ignore these letters in the future.

Nested Loops C programming - I need to scan input to find sets of letters

I am trying to write a function to scan in a string and find sets of the capital letter 'O'. Say my string is yyyOOOyyyOOyyyOyyy, it should print:
a group of 3 capital letter O's have been found together.
a group of 2 capital letter O's have been found together.
a group of 1 capital letter O's have been found together.
I cannot find a good way to do this. I'm trying to use nested loops, but I just don't have enough experience with it yet. Here is what I have come up with so far (I know it is completely non-functional). My code is also not allowing a user input using scanf (I have to use scanf for the assignment) Any help in correcting my loops and getting scanf to work would be great! Thanks!
void problem_03_function(){
char double_o_string[30];
scanf("%s", &double_o_string);
int count_double_o = 0;
char capital_letter_O = 'O';
int num_in_str = 0;
for(num_in_str; num_in_str < strlen(double_o_string); num_in_str++){
if(double_o_string[num_in_str] == capital_letter_O){
count_double_o++;
}
printf("a group of %d capital letter O's have been found togeth$
}
}
In order to avoid having two places to print the message, one for Os in the middle of the string and an extra check for Os at the end, I'd suggest a solution like the following, where an inner loop consumes a sequences of characters until the a non-O or the EOF is consumed, and the outer loop prints a message if the leading sequence of Os was non-empty:
#include <stdio.h>
int main() {
int c, count;
do {
for (count=0; (c = getchar()) == 'O'; count++) {}
if (count)
printf("a group of %d O's found.\n", count);
} while (c != EOF);
return 0;
}
Here is the same with a string pointer instead of getchar():
void test(char *p) {
int c, count;
do {
for (count=0; (c = *(p++)) == 'O'; count++) {}
if (count)
printf("a group of %d O's found.\n", count);
} while (c != 0);
}
You might need to do something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int* findSet(char *p) {
char cTS = 'o';
int i = 0;
int lastFound = 0;
int *array = malloc(sizeof(int) * 10); /* You can do better by allocating
dynamically because this will limit you to 10 sets only. */
int count = 0;
int lastPos = 0;
int strle = strlen(p);
for(; i < strle; i++) {
if(p[i] == cTS) {
count++;
lastFound = 1;
if(i == strle - 1) {
if(lastPos >= 10) return array;
array[lastPos++] = count;
break;
}
}
else {
if(lastFound) {
if(lastPos >= 10) return array;
array[lastPos++] = count;
}
count = 0;
lastFound = 0;
}
}
for(; 10 - lastPos;) {
array [lastPos++] = 0;
}
return array;
}
int main() {
int *x = findSet("ohoHeloooloo");
int i = 0;
for(; i < 10; i++) {
printf("%d", x[i]);
}
return 0;
}
Notice that you can change what you want to search for by changing cTS variable.
void show_fn(){
char double_o_string[30];
scanf("%s", double_o_string);
int count_double_o = 0;
int flag=0;
char capital_letter_O = 'O';
int num_in_str = 0;
for(num_in_str; num_in_str < strlen(double_o_string); num_in_str++){
if(double_o_string[num_in_str] == capital_letter_O){
flag=1;
count_double_o++;
if(num_in_str+1==strlen(double_o_string)){printf("a group of %d capital letter O's have been found together\n",count_double_o);}
}else{
if(flag==1){
printf("a group of %d capital letter O's have been found together\n",count_double_o);
count_double_o=0;flag = 0;
}
}
}
}
Try this:
void problem_03_function(){ // homework? ;)
char double_o_string[30];
scanf("%s", double_o_string); // Without & as double_o_string is already a pointer. See http://stackoverflow.com/questions/5406935/
int count_double_o = 0;
char capital_letter_O = 'O';
int num_in_str = 0;
int notice_not_printed = 0; // EDIT: simplified version of #kkaushi's answer
for( ; num_in_str < strlen(double_o_string); num_in_str++){ // You don't really need the first statement of for statement here
if(double_o_string[num_in_str] == capital_letter_O){
count_double_o++;
notice_not_printed = 1;
} else if (count_double_o) { // to prevent printing "a group of 0 capital..."
printf("a group of %d capital letter O's have been found together\n", count_double_o);
count_double_o = 0; // you need to reset the capital O count
notice_not_printed = 0;
}
}
// Used if the string ends with 'O'. See #kkaushi's answer
if (notice_not_printed)
printf("a group of %d capital letter O's have been found together\n", count_double_o);
}
void problem_03_function(){
const char capital_letter_O = 'O';
char double_o_string[30];
scanf("%s", &double_o_string);
int i = 0, o_gp= 0, o_gp_flag[3] = {0};
int len = strlen(double_o_string);
while(i < len){
o_gp = 0;
while(double_o_string[i++] == capital_letter_O){
if(++o_gp == 3 || i == len)break;
}//when o_gp > 3 , skip ?
if(o_gp)
o_gp_flag[o_gp-1] = 1;
}
for(i=0;i<3;++i)
if(o_gp_flag[i])
printf("a group of %d capital letter O's have been found togeth\n", i+1);
}
I think if you put this in your loop, it will work.
if(double_o_string[num_in_str] == capital_letter_O){
count_double_o++;
}
else if(count_double_o != 0) {
printf("a group of %d capital letter O's have been found togeth", count_double_o)
count_double_o = 0;
}

why my program "creating index" doesn't work?

I am coding a program which takes a text file as an input, makes the index of the words of it and prints the output(the index) in a file and in the screen. I coded as below and tried much to spot the problem or at least narrow it down, but I couldn't. If anyone can help or spots a problem in syntax or the logic of the code, I would be happy to know.
void main(int argc, char * argv[])
{
//clearscreen
clrscr();
//if arguments are less that default of the program
if (argc < 2)
{
cout << "You should've input 3 arguments." ;
return;
}
//opening the input file and defining a pointer which points to it as argv[1]
FILE *fPtr = fopen(argv[1], "r+");
//defining a 2D array to hold maximum to 200 words holding maximum to 20 characters
char words[200][20];
//initializing words 2D array with zero ASCII
for(int i = 0; i < 200; i++)
for(int j = 0; j < 20; j++)
words[i][j] = 255;
//defining an 2D whi array which is supposed to show how many times words are placed in which lines in a defined layout
//it holds maximum to 200 words holding maximum 100 sentences
int index[200][100];
//initializing the index 2D array with zero ASCII
for(i = 0; i < 200; i++)
for(j = 0; j < 100; j++)
index[i][j] = 0;
//this array of characters max to 2000 is supposed to hold each line which is gotten with fgets
char buff[2000];
//initializing the buff array with zero ASCII
for(i = 0; i < 2000; i++)
buff[i] = 0;
//the max of the words used in the source file is 200. but this valuable named as 'last' says how many words are used in this source file
//its initalized as no words is held
int last = 0;
//defining a pointer to char of punctuation mark characters. all ASCII codes expect for a - z, A - Z, 0 - 9 and newline
char *punc;
//initializing punctuation marks array
for(i = 0; i < 256; i++)
{
if(i == 10)
continue;
if(i >= '0' && i <= '9')
continue;
if(i >= 'a' && i <= 'z')
continue;
if(i >= 'A' && i <= 'Z')
continue;
char *string = (char *) &i;
strncat(punc, string, 1);
}
//how many lines is read from the source file
int lineread = 0;
//a word which the processes are done on that
char *word;
//one line read
while( fgets(buff, 1999, fPtr) != NULL)
{
//how many words is read from the source file in the current line
int wordread = 0;
word = strtok(buff, punc);
//one word read
while( word != NULL)
{
//sorting
int k = 0;
while(strcmp(word, words[k])> 0)
k++;
if(strcmp(word, words[k]))
{
for(int l = last; l >= 0; l--)
{
strcpy(words[l + 1],words[l]);
for(int o = 0; o <= lineread; o++)
index[l + 1][o] = index[l][o];
}
last++;
strcpy(words[k],word);
for(l = 0; l <= lineread; l++)
index[k][l] = 0;
}
index[k][lineread]++;
wordread++;//go to next word
word = strtok(NULL, punc);
}
lineread++;//go to next line
}
//closing the input file
fclose(fPtr);
//opening the output file and defining a pointer which points to it as argv[2]
FILE *fPtr2 = fopen(argv[2], "w+");
//showing the index in cmd
for(i = 0; i <= last; i++)
{
printf("%-20s" , words[i]);
fprinf(fPtr2, "%-20s" , words[i]);
int m = 0;
for(j = 0; j <= lineread; j++)
{
if(m)
{
printf("%c", ',');
fprintf(fPtr2, "%c", ',');
}
if(index[i][j])
{
printf("%i", j + 1);
fprintf(fPtr2, "%i" ,j + 1);
}
if(index[i][j] > 1)
{
printf("(%i)", index[i][j]);
fprintf(fPtr2, "(%i)", index[i][j]);
m = 1;
}
}
printf("\n");
fprintf(fPtr2, "\n");
}
//closing the output file
fclose(fPtr);
}
now it errors as Abnormal program termination NULL pointer assignment. I have to use turbo c and I use DOS SHELL. there's a file names as "input.txt" in resourse. and in DOS SHELL I write this:
programname.exe input.txt output.txt
and my desired output if input.txt is this:
hello. hello.
how are
you? hello.
desired output:
hello 1(2),3 //2 times in line 2, 1 time in line 1
how 2 //1 time in line 2
are 2 //1 time in line 2
you 3 //1 time in line 3
the problem is with this line:
while(strcmp(word, words[k])> 0)
Because index is initialized as 255 and according to the algorithm strcmp works based on, for first word the code works right and puts it in word[0] but for the second word it won't work properly.for example:
first word: Kittens
second word: Biscuits
first strcmp compares Kittens with 255 ASCII code. the result is that Kitten is smaller and the process will put it in word[0]. But for the second word, strcmp compares Biscuits with Kittens and the result is that Kittens is bigger and program will go through another blocks of word[] which in not wanted. the program will be fixed by initializing word[] to 0 and using this code instead of that which is first mentioned:
while(strcmp(word, words[k])> 0)

Resources