Word finder not outputting as expected - c

the code is supposed to output all possible word combinations without any whitespace but with this method, it gives me whitespace
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char letters[6];
int on = 0;
int results;
printf("input the words all together: ");
scanf("%s", letters);
if (strlen(letters) == 6) {
for (int i = 0; i <= 6; i++) {
for (int j = 0; j <= 6; j++) {
for (int k = 0; k <= 6; k++) {
for (int l = 0; l <= 6; l++) {
for (int m = 0; m <= 6; m++) {
for (int n = 0; n <= 6; n++) {
char wordNow[6] = {
letters[i],
letters[j],
letters[k],
letters[l],
letters[m],
letters[n]
};
printf("%s\n", wordNow);
results = results+1;
}
}
}
}
}
}
}
printf("%d", results);
return 0;
}
This code is supposed to take in 6 characters and produce all possible combinations using those characters. When I use that method, the combinations end up repeating and gives me whitespace.
My old method that works but adds whitespace is:
printf("%c %c %c %c %c %c\n",
letters[i], letters[j], letters[k],
letters[l], letters[m], letters[n]);
If anyone could help, I would appreciate it.

wordNow is not null terminated, leading to the output you are seeing. Also, results is not initialized.

You'll need to null terminate your string if you plan to print it, since printf will keep iterating over the characters in the string until it hits the null terminator:
char wordNow[7] = {
letters[i],
letters[j],
letters[k],
letters[l],
letters[m],
letters[n],
'\0' // <-- added
};
int results; should be int result = 0; as Brady points out.
You might want to run your loops up to < rather than <= if you want to omit null terminators.

Related

printing * corresponding to the number of iteration

So in C I'm supposed to let the user input an integer n from the interval [5, 25]. And then, for every number from 1 to n, in a new line print that many stars so it would look something like this:
*
**
***
I tried doing it like this, but it's not working. What am I doing wrong here?
#include <stdio.h>
int main(void)
{
int n, i;
char star = '*';
do {
printf("Input an int from [5, 25]");
scanf("%d", &n);
} while (n < 5 || n >= 25);
for (i=0; i < n; i++){
star += '*';
printf("%c", star);
}
return 0;
}
You cannot write star += '*'; because you declared star as a char, C is strongly typed, a char is a char not a table of char.
You have to use nested loop, like this for example:
#include <stdio.h>
int main(void)
{
int n, i, j;
char star = '*';
do
{
printf("Input an int from [5, 25]");
scanf("%d", &n);
} while (n < 5 || n >= 25);
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i; j++)
{
printf("*");
}
printf("\n");
}
return 0;
}
You need nested loops
for (int i=0; i < n; i++)
{
for(int j = 0; j <= i; j++)
printf("*");
printf("\n");
}
or if you want to use strings:
char str[n + 1];
for (int i=0; i < n; i++)
{
str[i] = '*';
str[i + 1] = 0;
puts(str);
}
https://godbolt.org/z/aT8brP1ch
The statement
star += '*';
is not the correct way to concatenate two strings in C. In order to do this, you can define an array with sufficient space for the string and use the function strcat, like this:
#include <stdio.h>
#include <string.h>
int main(void)
{
int n;
//initialize "stars" to an empty string
char stars[20] = {0};
do {
printf("Input an int from [5, 25]: ");
scanf("%d", &n);
} while (n < 5 || n >= 25);
//build the string containing the stars using repeated
//string concatentation
for ( int i = 0; i < n; i++ ) {
strcat( stars, "*" );
}
//print the string
printf( "%s\n", stars );
return 0;
}
This program has the following behavior:
Input an int from [5, 25]: 5
*****
However, this is highly inefficient and unnecessarily complicated. Instead of first building the string in an array before printing it out all at once, it is usually easier to simply print it one character at a time:
#include <stdio.h>
#include <string.h>
int main(void)
{
int n;
do {
printf("Input an int from [5, 25]: ");
scanf("%d", &n);
} while (n < 5 || n >= 25);
//print the stars one character at a time
for ( int i = 0; i < n; i++ ) {
putchar( '*' );
}
//end the line
putchar( '\n' );
return 0;
}
This program has the same output as the first program.
You now have the solution for printing out a single line. However, your task involves printing out several lines. This will require a nested loop. In accordance with the community guidelines on homework questions, I will not provide the full solution at this time, as you should attempt to do this yourself, first.
char is an integral type - that is, it represents a number. '*' is a Character Constant, which actually has the type int.
char star = '*';
star += '*';
In ASCII, this is no different from
char star = 42;
star += 42;
A string is a series of nonzero bytes, followed by a zero byte (the null terminating character, '\0'). You cannot build a string by adding two integers together.
To build a string, you must place each byte in a buffer in sequence, and ensure a null terminating byte follows.
#include <stdio.h>
#define MIN 5
#define MAX 25
int main(void)
{
int n;
do {
printf("Input an int from [%d, %d): ", MIN, MAX);
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Failed to parse input.\n");
return 1;
}
} while (n < MIN || n >= MAX);
char buffer[MAX + 1] = { 0 };
for (int i = 0; i < n; i++) {
buffer[i] = '*';
buffer[i + 1] = '\0';
puts(buffer);
}
}
Aside: never ignore the return value of scanf.
Or you can avoids strings, and just print the characters directly.
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++)
putchar('*');
putchar('\n');
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int n,i,j;
printf("enter a number between 5 & 25");
scanf("%d",&n);
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
printf("*");
}
printf("\n");
}
return 0;
}
String concatenation does not work like that in C, instead use strcat().

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;
}

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.

How to read multiple digit number from a string

I am trying to pass a string S as input. Here the string S can contain multiple integer values followed by an alphabet. The program must expand the alphabets based on the previous integer value.
Consider the Input: 4a5h
For which the Output: aaaahhhhh, that is 4 times a and 5 times h
Also for Input: 10a2b
Output: aaaaaaaaaabb, that is 10 times a and 2 times b
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char s[1000], alp[1000];
int num[1000];
int n = 0;
int i, j, k, m;
k = 0;
scanf("%[^\n]s", s);//Reads string until newline character is encountered
for (i = 0; i < strlen(s); i++) {
if (isalpha(s[i])) {
alp[n] = s[i]; // alp[] stores the alphabets
n += 1;
} else {
num[k] = s[i] - '0';// num[] stores the numbers
k += 1;
}
}
for (i = 0; i < k; i++) {
for (m = 0; m < num[i]; m++)
printf("%c", alp[i]);
}
return 0;
}
But with this code I am not able to read 2 or 3 or a N digit number. So if the Input is 100q1z then the alp[] array is fine but num[] array is not containing 100 and 1 as its elements instead 1 and 0 are its elements.
How do I correct this code?
You should modify the loop to handle as many digits are present successively int the string:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char s[1000], alp[1000];
int num[1000];
int i, k = 0, m, n;
//Read string until newline character is encountered
if (scanf("%999[^\n]", s) == 1) {
for (i = 0; s[i]; i++) {
n = 1;
if (isdigit((unsigned char)s[i])) {
for (n = s[i++] - '0'; isdigit((unsigned char)s[i]); i++) {
n = n * 10 + s[i] - '0';
}
}
if (isalpha((unsigned char)s[i])) {
alp[k] = s[i]; // store the letter
num[k] = n; // store the number
k += 1;
}
}
for (i = 0; i < k; i++) {
for (m = 0; m < num[i]; m++)
putchar(alp[i]);
}
}
putchar('\n');
return 0;
}
Notes:
include <ctype.h> to use isalpha().
protect the destination array of scanf by passing a maximum number of characters and check the return value.
the format for converting a non empty line is simply %[^\n], the trailing s is incorrect. Note that unlike fgets(), this scanf() format will fail if the line is empty.
you should always test the return value of scanf().
cast the char argument to isalpha() and isdigit() as (unsigned char) to avoid undefined behavior if char is signed and has a negative value.
use putchar(c) to output a single character instead of printf("%c", c);
The part of else-bolock must be looped.
like this
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> //need this for isalpha and isdigit
int main(void){
char s[1000], alp[1000];
int num[1000];
int m = 0, n = 0;
int i, j;
unsigned char ch;//convert char to unsigned char before use isalpha and isdigit
scanf("%999[^\n]", s);//remove s after [^\n] and Add limit
for(i = 0; ch = s[i]; i++){//replace strlen each loop
if(isalpha(ch)){
alp[n++] = s[i];
} else if(isdigit(ch)){
num[m] = 0;
while(isdigit(ch = s[i])){
num[m] = num[m] * 10 + s[i] - '0';
++i;
}
++m;
--i;//for ++i of for-loop
} else {//Insufficient as validation
printf("include invalid character (%c).\n", ch);
return -1;
}
}
for(i = 0; i < m; i++){
for(j = 0; j < num[i]; j++)
printf("%c", alp[i]);
}
puts("");
return 0;
}
The problem with the code is that when you encounter a digit in the string, you are considering it as a number and storing it in num array. This is fine if you have only single digit numbers in the array. For multidigit numbers do this- read the string for digits until you find a alphabet, form a number using the obtained digits and then save it to num array.I m leaving the code for you.

String array prints out trash values

So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10

Resources