c program for word ladder - c

I have written C code for word ladder.
It is validating for given test cases. but for 1 test case it's output is wrong I'm not getting where should I make changes.
Question
There is a class of word puzzles where you are given two words, such as BEAK and MAKE, and have to get from one to another by changing one letter at a time. Solving such puzzles requires a good vocabulary and some lateral thinking, but checking the solution once you have one is merely tedious and suitable for a computer to do. Note that even correct solutions are not guaranteed to be minimal.
A solution is correct if, for each pair of adjacent words in the ladder, the following apply:
they are the same length
there is exactly one letter changed.
Write a program that will check proposed solutions.
Input Format:
Input will be a solution i.e it consists of a series of words, one per line, terminated
by a line containing a single #. A word is a sequence --- between three and twenty uppercase letters.
Output Format:
Output the word ‘Correct’ or ‘Incorrect’ as appropriate.
Sample Input 1:
BARK
BARE
#
Sample Output 1:
Correct
Sample Input 2:
MAKE
BAKE
BONK
BONE
BANE
#
Sample Output 2:
Incorrect
My code
#include<stdio.h>
#include<string.h>
int main()
{
int i,count;
char a[100],b[100],c[100];
int flag=1;
scanf("%s",a);
do
{
scanf("%s",b);
if(b[0]=='#')
break;
if(strlen(a)==strlen(b))
{ i=0,count=0;
while(a[i]!='\0')
{
if(a[i]!=b[i])
count++;
if(count==2)
{
flag=0;
}
i++;
}
}
else
{
flag=0;
}
scanf("%s",a);
if(a[0]=='#')
break;
// scanf("%s",c);
strcpy(c,a);
strcpy(a,b);
strcpy(b,c);
}
while(a[0]!='#');
if(flag==1)
printf("Correct");
else
printf("Incorrect");
return 0;
}
programs output is incorrect for this input
code -> cade -> cate -> date -> data

You are reading words too many times. I mean, you read more than you compare.
Check this out:
first scanf() (into a) doesn't count. It's used to have something to compare
second scanf() (into b) in the loop
comparison of a and b in the loop
third scanf() (into a) in the loop!!
repeat at 2.
You should only have 1 scanf() and 1 comparison inside the loop.
Also your indentation hurts.

Related

Why program is giving unexpected output?

I'm stuck in a problem given in a book. The problem is -
The prototypical Internet newbie is a fellow name B1FF,who has a unique way of wriring messages.Here’s a typical B1FF communique.:
H3Y DUD3, C 15 R1LLY C00L
Write a “B1FF filter” that reads a message entered by the user and translates it into B1FF-speak:
Enter message: Hey dude, C is rilly cool
In B1FF-speak : H3Y DUD3, C 15 R1LLY C00L
Your program should convert the message to upper-case letters,substitute digits for certain letters (A=4,B=8,E=3,I=1,O=0,S=5).
My Program-
#include<stdio.h>
int main()
{
char arr[50]={0},ch[50]={0};
int i=0;
printf("\nenter the sentence : ");
while(arr[i-1]!='\n')
{
scanf("%c",&arr[i]);
i++;
}
i=0;
while(arr[i]!='\n')
{
if(arr[i]=='e')
ch[i]='3';
if(arr[i]==('A'||'a') )
ch[i]='4';
if(arr[i]==('B'||'b'))
ch[i]='8';
if(arr[i]==('I'||'i'))
ch[i]='1';
if(arr[i]==('o'||'O'))
ch[i]='0';
if(arr[i]==('S'||'s'))
ch[i]='5';
else ch[i]=arr[i]-32;
i++;
}
ch[i]='\n';
i=0;
printf("\nIn B1FF-SPEAK : ");
while(ch[i]!='\n')
{
printf("%c",ch[i]);
i++;
}
printf("\n");
return 0;
}
OUTPUT OF THE PROGRAM-
I don't understand why the program is not converting the alphabets and why scanf() is not accepting space as a character ?
First and foremost, you cannot chain the logical OR operator like
if(arr[i]==('A'||'a') )
and get what you're expecting, because this resolves to an always TRUE condition. [('A'||'a') evaluates to TRUE]
You have to use
if ( (arr[i]=='A') || (arr[i] =='a'))
That said,
ch[i]=='8';, ch[i]==1; are basically empty statements. You're comparing and discarding the comparison result. If you want assignment, you need to use =.
the else ch[i]=arr[i]-32; only binds with the previous if statement, no the whole if chains. You can either make use of switch case or if-else if-else constructs to take care of that part.
you did not handle whitespaces separately.
To elaborate, due to the second point above, you code basically reduces to
while(arr[i]!='\n')
{
if(arr[i]==('S'||'s')) //always false
ch[i]='5';
else ch[i]=arr[i]-32; //always TRUE
i++;
}
which is just a poor attempt to convert lowercase to UPPERCASE. In case a non-alpha input is there in the string, the code will blow up.
That said, regarding the
why scanf() is not accepting space as a character?
part, scanf() perfectly accepts a space as an input with %c, it's you just convert it no NUL (null) by blindly subtracting 32 from a space which has an ASCII value of decimal 32. A NUL is non printable, and does not appear in the output.
Some recommendations:
Don't use lots of little calls to scanf("%c"...). Use fgets() (manpage). fgets reads in a whole line from input, stores it in your buffer (including the newline), and sticks a '\0' byte at the end of it so you know how long the string is.
use toupper() (manpage). It takes an arbitrary character as input. If the input is a lower case letter, then the output is the upper-case version of that letter. Otherwise, the output is the same as the input.
Update the array in-place. You don't need two arrays. Read the array with fgets(), loop over it with your translation logic, updating each character as you go, then write the array out with fputs().
Learn about switch statements. A switch statement will make your code more compact and easier to read. You need one case for every letter->number transform, and a default case for everything else.
c = toUpper(c);
switch (c) {
case 'A': c = '4'; break;
case 'B': c = '8'; break;
....
default: break;
}

Inverting a phrase and write it weirdly with c

my programming teacher have sent some exercises for practice, and this one I've no clue for a way to solve it.
In his example, he asks: write a program that gets a phrase or a word, turn it backwards and write it weirdly.
I'm trying to use the phrase "ABCDE" write it backwards and then, start writing the phrase from the middle.
In the end, he wants something like: CBAED
All I have so far, is the phrase/word backwards, like: EDCBA
Well, this is my code so far:
#include <stdio.h>
void inverter();
int main(){
printf("sentence to revert: ");
inverter();
return 0;
}
void inverter(){
char letra;
scanf("%c",&letra);
if( letra != '\n'){
inverter();
printf("%c",letra);
}
}
As you guys have seen, I'm a newbie in C (and in English) so, if any of you could give me a way to proceed, I would appreciate it a lot.
Edit: I believe I was not happy on the phrase I've selected as an exemple, so I've changed it.
Without telling you exactly the code to write, because you are asking for help with academic work, you can try this:
Read in a line of text.
Using the length of the line (scanf returns an int with the number of characters read if I'm not mistaken), loop through it backwards, printing each character at a time.
Something to try would be like this:
//This is pseudocode. Do not copy/paste
for(int i = length of line; i > 0; i--) {
print out line[i];
}
Then divide the length by 2 and run two loops in reverse, one starting in the middle:
//This is Psuedocode. Do not copy/paste
for(int i = middle of line; i > 0; i--) {
print out line[i];
}
And then another starting at the end:
//This is Pseudocode. Do not copy/paste
for(int i = length of line; i > middle of line; i--) {
print out line[i];
}
????
Profit
Obviously, you will have to tweak a few things here and there. For example, i = length of line will cause a runtime error, but you're here to learn and I believe in learning by doing.

Why am I getting a segmentation fault here (C)

I keep getting a segmentation fault in the line array[j]=array[j]+1.
I've included the portion of the main function used to call "mode", function which is the one I'm having trouble with. The program is supposed to take user input in the form of a string. Depending on what the string says the function does different things. For input "mode" it takes an array from the user and then finds the mode, or number that appears most often. The program may not be the cleanest or most efficient, but I just need it to work. Thank you for any help.
int mode(int input[]){
int array[30]={0},i=0,j=0,i2=0,j2=0;
while (input[i]!='\0'){
j=input[i];
array[j]=array[j]+1;
i++;
}
while (array[i2]!='\0'){
if (array[i2]>j2){
j2=array[i2];
i2++;
}
else{
i2++;
}
}
return j2;
}
int main(){
char function_called[7];
int nums_for_mode[50],num_for_primes;
int num1,den1,num2,den2;
printf("Please choose a function (mode, primes, or fradd): ");
scanf("%s",&function_called);
if(strcmp(function_called, "mode")==0){
printf("\nPlease provide numbers between 1 and 30: ");
scanf("%i",&nums_for_mode);
printf("\nThe mode is %i\n",mode(nums_for_mode));
}
nums_for_mode is uninitialized, and you don't terminate it either.
Near the top of main, set each member of nums_form_mode to 0:
for(int a = 0; a < 50; a++)
nums_for_mode[a] = 0;
or, initialize it with ={0} at the declaration point. Fixing this will stop your segfault, but the program is still wrong:
You should also get the numbers in a loop, currently, your program only actually receives one number.
array[30] will be easy to overflow, including if you enter 30. You should make it one longer at least, and also check that the input actually is in range when reading it.
The function_called buffer is too small and prone to overflow, you should limit the size of input in the call to scanf.
this line: while (array[i2]!='\0') doesn't make much logical sense, it will terminate early without actually checking over the input.

How does sscanf() see numbers in a string?

I have a problem with sscanf() in the following code:
void num_check(const char*ps){
char *ps1=NULL;
int number=0;
unsigned sum_num=0;
ps1=ps;
for(;*ps1!='\0';ps1++){
if (isdigit(*ps1)){
sscanf(ps1,"%d",&number);
sum_num+=number;
}
}
printf("Sum of digits is: %d",sum_num);
}
int main(){
printf("Enter a string:\n");
char str[20];
gets(str);
num_check(str);
return 0;
}
The problem is: when I input a string in the form of "w2b4e" it sums my numbers OK, and I get the desired result. But when I try to input a string such as "w23b4e", what it does is: it sees the number 23 in the loop, so variable number=23, and sum_num=23, but the next step in the loop is this: number=3, and sum_num=26. And in the next step sum_num= 30...
This confuses me quite a bit. Since I don't believe that sscanf() has such a quirky flaw, what am I doing wrong?
You always advance by exactly one character in the loop: ps1++. You probably want to advance ps1 to the first digit instead.
Better yet, there's a function called strtol. It tries to parse integers from strings and can return the position of the first character that could not be read. So you can use strtol in a loop to sum everything that looks like a number in your string.
If you want to sum digits instead of numbers found in a string, it's easier:
while (*p) {
if (isdigit(*p))
sum_num += *p - '0';
}
If you want to sum digits (not the whole number), use the following instead:
if( isdigit(*ps1)) {
sum_num += *ps1 - '0';
}
You can also use sscanf("%1d", ps1) to make it read only one character.
for(;*ps1!='\0';ps1++){
if (isdigit(*ps1)){
sscanf(ps1,"%d",&number);
sum_num+=number;
}
}
you are incrementing ps1 one character at a time, independently of how many digits are being read. Unfortunately you cannot use sscanf for this task, since you are not able to know how many characters have been read.
sscanf works like it should, it doesn't move beginning of pointer, you are moving it by one character in for loop.

Having a hard time using getchar and storing characters

I am new to programming in C and still trying to learn all of the useful functions it provides in its libraries. In particular I'm trying to wrap my head around how to use getchar() for more than one character in a certain situation. I want to be able to have input from the console be something like:
11 2 34 100
I want to be able to distinguish between these entries(delimiter space I guess?), and add these numbers up. This is an assignment, so I was wondering if someone could give me a hint or point me in the right direction on how to go further with this. I would certainly appreciate it. This is what I have at the moment. Also, we're not supposed to make use of arrays here. This really threw me because I don't see any other way. Again any help or pointers in the right direction would go a long way!
int main()
{
int count = 0;
char input;
int wordCount = 0;
int numEntered = 0;
input = getchar();
while(input != '\n')
{
if(input != ' ')
{
count++;
}
input = getchar();
}
printf("Number of characters included in numbers %d\n", count);
return 0;
}
You can store two integers, one that is the running total, and one that is the current number.
If you encounter a digit that is not a space, multiply the current number by 10 and then add that digit to the current number.
If you encounter a space, add the current number to the running total, then reset the current number to 0.

Resources