Luhn Algorithm sometimes work sometimes fail [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
If it fits the algorithm, it should have an output of true and if it doesn't, the output should be false. Any idea where it goes wrong?
I tried
1586455534096 ; output : false(fail)
49927398716 ; output : true (ok)
984697300577 ; output : false (fail)
Code
#include<stdio.h>
#include<string.h>
int main()
{
char str[100];
int n,num[100],prod[100],remainder,sum,total;
scanf("%s", str);
for(n=0;n<100;n++)
{
if(str[n]==0) break;
num[n] = str[n] - '0';
if(n%2!=0)
{
prod[n]=num[n]*2;
sum=0;
while(prod[n]>=10)
{
remainder=prod[n]%10;
sum=sum+remainder;
prod[n]=prod[n]/10;
}
num[n]=sum;
}
total = total + num[n];
}
if(total%10==0)
printf("true\n");
else
printf("false\n");
return 0;
}

Your code working.
#include<stdio.h>
#include<string.h>
int main()
{
char str[100];
int n,num[100],prod[100],remainder,sum,total=0;
scanf("%s", str);
for(n=0;n<100;n++)
{
if(str[n]==0) break;
num[n] = str[n] - '0';
if(n%2!=0)
{
prod[n]=num[n]*2;
sum=0;
while(prod[n]>0)
{
remainder=prod[n]%10;
sum=sum+remainder;
prod[n]=prod[n]/10;
}
num[n]=sum;
}
total = total + num[n];
}
if(total%10==0)
printf("true\n");
else
printf("false\n");
return 0;
}
Into your code there are 2 main problems:
no init value for total var at least
the inner while have to use >0 as condition.
My correction on your code
#include<stdio.h>
#include<stdint.h>
#include<string.h>
int main()
{
char format[32];
char str[100]={0};
uint32_t n=0;
uint32_t num = 0;
uint32_t total=0;
snprintf(format, sizeof(format), "%%%zus", (sizeof(str)/sizeof(str[0]))-1 );
scanf(format, str);
while (str[n] != '\0')
{
num = str[n] - '0';
if(n%2!=0)
{
num*=2;
while(num>0)
{
total += num%10;
num/=10;
}
}
else
{
total += num;
}
n++;
}
if(total%10==0)
printf("true\n");
else
printf("false\n");
return 0;
}

At first glance total is uninitialized and having uninitialized values in the code leads to indeterminate values

You never initialize total before you use it, which means its value is indeterminate and giving you undefined behavior. Might be the same with other variables.
Initialize the variables on declaration, like e.g.
int n, num[100] = { 0 }, prod[100] = { 0 }, remainder = 0, sum = 0,total = 0;

Related

Comparing the permutations of two strings in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I've just started out with learning C-basics and tried solving this problem where, we have to check if two strings are equal provided any permutation.
You may refer to this link: https://www.hackerearth.com/practice/basic-programming/input-output/basics-of-input-output/practice-problems/algorithm/two-strings-4/
I just wanted to get some solutions on how can I improve my code which gives the output as only 'NO':
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int i, j, k, m, n, o, p;
char a[100000], b[100000], *c, *d;
scanf("%d", &i);
for (j = 0; j < i; j++)
{
scanf("%s %s", a, b);
}
for (k = 0; a[k] != '\0'; k++)
{
n = rand() % k;
}
for (m = 0; b[m] != '\0'; m++)
{
o = rand() % m;
}
for (p = 0; p < j; p++)
{
if (a[n] == b[o])
{
printf("YES");
}
else
{
printf("NO");
}
}
return 0;
}
Thanks for the help!
It is unclear what you are trying to achieve from the rand() function but certainly you need now to find different permutations to do that. Permutations of string s1 should be equal to string s2 which means all character in string s1 should be present in s2 and count of each of those characters in both the strings should be same
Here is a working version:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//CHECKING IF STRING TWO IS ANY PERMUTATION OF STRING ONE
int main()
{
char str_one[]="abbcd";
char str_two[]="bcab";
int arr[26]={0};
int index=0;
int len_one=strlen(str_one);
int len_two=strlen(str_two);
int val;
if(len_one!=len_two)
{
printf("NO");
exit(0);
}
while(index<len_one)
{
++arr[str_one[index++]-'a'];
}
index=0;
while(index<len_two)
{
--arr[str_two[index++]-'a'];
if(arr[str_two[index]-'a']<0)
{
printf("NO");
exit(0);
}
}
index=0;
while(index<26)
{
if(arr[index]!=0)
{
printf("NO");
exit(0);
}
++index;
}
printf("yes");
return 0;
}
As you only want some suggestions about the improving your code.
You may use scanf("%20s", str1) or something like that to improve the memory footprint of your answer. You will need to use a loop to read the strings. %20s asks scanf to read 20 characters at most. You can tailor the number according to your needs.
You can get the length of the string via strlen function included from string.h.
You just want to check the occurrence times of each character. In your case you can use an integer array of length 26, or two depending on your algorithm.
Use better variable names. This really helps if you do something wrong in algorithm.
This would be my solution just for one string comparision
Detailed Evaluation of User Code
for (j = 0; j < i; j++)
{
scanf("%s %s", a, b);
}
This code block reads all lines. C is evaluated sequentially, so instead you will need to do this like
for (j = 0 ; j < i ; j++)
{
scanf("%s %s", a, b);
/* do comparision for each here */
}
As I mentioned above C is evaluated sequentially, so the next 2 for loops also evaluates and results in a randomly selected 2 characters from both strings. I did not analyzed the probability, but from my senses I can say it won't hit same character most of the time. It is better to loop over a string, than pray for RNG to hit.
for (k = 0; a[k] != '\0'; k++)
{
n = rand() % k;
}
for (m = 0; b[m] != '\0'; m++)
{
o = rand() % m;
}
The above code will execute and only produces 1 output for each for loop and due to randomness of it I cannot tell which outcome it will lead.
for (p = 0; p < j; p++)
{
if (a[n] == b[o])
{
printf("YES");
}
else
{
printf("NO");
}
}
This for loop will execute exactly i times as the current value of j will be i as the first for loop executed before. Each of these loops will compare the same a[n] and b[o] from the reasons explained above. so the outcome will be YESxi or NOxi. No matter what the strings are.
Hope this explains what is wrong with your code.
For compare two string use of strcmp() :
int strcmp(const char *str1, const char *str2)
Parameters :
str1 − This is the first string to be compared.
str2 − This is the second string to be compared.
Return Value :
This function return values that are as follows :
if Return value < 0 then it indicates str1 is less than str2.
if Return value > 0 then it indicates str2 is less than str1.
if Return value = 0 then it indicates str1 is equal to str2.
Example :
#include <stdio.h>
#include <string.h>
int main () {
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strcmp(str1, str2);
if(ret < 0) {
printf("str1 is less than str2");
} else if(ret > 0) {
printf("str2 is less than str1");
} else {
printf("str1 is equal to str2");
}
return(0);
}

Stuck with comparing Strings in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So im supposed to write a Soundex Converter code and print the lines from a file if one of its words has the same Soundex code as the input. I successfully wrote a function for the Soundex conversion but im stuck at the comparing part. Sorry if this sounds trivial but when i compare the words line by line, strcmp seems to fail everytime. Here's the code... Sorry if its too long
#include<string.h>
#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
char *soundex(char *s,char* name)
{
int si = 1;
char c;
//char *s = (char *)malloc(1000);
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
char mappings[] = "01230120022455012623010202";
s[0] = toupper(name[0]);
for(int i = 1, l = strlen(name); i < l; i++)
{
c = toupper(name[i]) - 65;
if(c >= 0 && c <= 25)
{
if(mappings[c] != '0')
{
if(mappings[c] != s[si-1])
{
s[si] = mappings[c];
si++;
}
if(si > 3)
{
break;
}
}
}
}
if(si <= 3)
{
while(si <= 3)
{
s[si] = '0';
si++;
}
}
//printf("%s\n",s);
return s;
}
void search(char line[10000],char str[1000])
{
int i,j=0;
char test[1000];
char s[1000];
char b[1000];
for(i=0;line[i] != '\0';i++)
{
if(line[i] == ' ')
continue;
test[j] = line[i];
j++;
if(line[i+1] == ' ' || line[i+1] == '\0')
{
//soundex(test);
test[j] = '\0';
if(strcmp(soundex(s,test),soundex(b,str)) == 0);
{
printf("%s\n",soundex(s,test));
printf("%s\n",soundex(b,str));
printf("%s",line);
break;
}
j = 0;
memset(test,0,strlen(test));
}
}
}
int main()
{
char a[1000],f[1000];
char s[1000];
gets(a);
//soundex(s,a);
//printf("%s",s);
scanf("%s",f);
FILE *fp=fopen(f,"r");
if(fp==NULL)
{
printf("File doesnot exist bro");
}
else
{
long long linenum=1;
char line[10000];
while(fgets(line,10000,fp)!=NULL) //Or fscanf
{
search(line,a);
//printf("%s",line);
linenum++;
}
}
fclose(fp);
}
The Problem is arising with the strcmp command in the Search function as it prints the lines even after the results differ. I even print the results of the comparison afterwards to be sure. Any leads would be aprreciated. Again sorry for the long code.
Take the ; off. Don't ignore compiler warnings!
prog.c:70:17: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
if(strcmp(soundex(s,test),soundex(b,str)) == 0);
if(strcmp(soundex(s,test),soundex(b,str)) == 0)
also
prog.c: In function ‘search’:
prog.c:68:25: warning: statement with no effect [-Wunused-value]
test[j] == '\0';
and
prog.c: In function ‘main’:
prog.c:89:9: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
gets(a);

To check if two words are equal to each other?(C) [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 6 years ago.
Hello.I want to make a simple English-Turkish dictionary. This is my homework.I have to code with C but I don't know C at all. Why doesn't my following code work?
#include<stdio.h>
int main()
{
int i;
char word_array[10][20] ={"araba","car","kalem","pencil","derin","deep","mavi","blue","el","hand" };
//char arama[5] = {'d','e','r','i','n'};
char search[10] = "araba ";
for(i = 0 ; i < 10; i=i+2){
if(word_array[i] == search){
printf("i found: %s\n",i);
}
else{
printf("The word isnt in the array. %s\n",word_array[i],search);
}
}
return 0;
}
Review the code below. It fixed few issues with your code.
#include<stdio.h>
#include <string.h>
int main()
{
int i;
char word_array[10][20] ={"araba","car","kalem","pencil","derin","deep","mavi","blue","el","hand" };
char search[10] = "araba";
for(i = 0 ; i < 10; i++){
if(strcmp(word_array[i],search) == 0){
printf("i found: %s\n",i);
break;
}
}
if(i>=10) {
printf("The word %s isnt in the array.\n",search);
}
return 0;
}
#include<stdio.h>
#include <string.h> // <-------- Include header containing strcmp()
int main()
{
int i;
char word_array[10][20] = { "araba", "car", "kalem", "pencil", "derin", "deep", "mavi", "blue", "el", "hand" };
//char arama[5] = {'d','e','r','i','n'};
char search[10] = "araba"; // <-------- Remove space to have the same string.
for (i = 0; i < 10; i = i + 1){ // <-------- Search each word in array as opposed to each second word.
if (strcmp(word_array[i], search) == 0){ // <-------- Use proper C-string comparison.
printf("%i found: %s\n", i, word_array[i]); // <-------- Correct specifier "i" to "%i" and add the actual found word to output for "%s"
}
else{
printf("The word isnt in the array. %s\n", word_array[i], search);
}
}
return 0;
}
Also see: How do I properly compare strings?

string palindrome in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am writing a program of string pallindrome, code is compiling successfully but on running it accepting the string but nothing after that, the output window stays on hold with cursor blinking, help me what is wrong with this code.
I am using dev-c++
gets(ch); // the program stops here
p=ch;
while(ch!='\0')
{ p++;
size++;
}
for(i=0;i<20;i++)
{
if(c[i]==c[j])
printf("string is pallindrome");
else printf("string is not pallindrome");
}
getch();
return 0;
}
Here is the problem:
while(ch!='\0')
ch is a char array, and you are comparing it with a single char.
Also, size is not initialised.
I would suggest something like this:
size=0;
while(ch[size]!='\0')
{ p++;
size++;
}
or, using the pointer method:
while(*p!=0)
{
p++;
size++;
}
Also, instead of printing inside the for loop (which would make it print several times), use a flag variable.
You only need one loop, for example while (i < i).
Look at this example that will do the job:
#include <stdio.h>
#include <string.h>
/* in c99 use <stdbool.h> instead*/
typedef int bool;
#define true 1;
#define false 0;
int main(void)
{
char ch[20];
puts("enter the string: ");
gets(ch);
size_t size = strlen(ch);
bool pallindrome = true;
int j = size-1;
int i = 0;
while (i < j)
{
if(ch[i] != ch[j]) {
pallindrome = false;
break;
}
++i;
--j;
}
if (pallindrome)
printf("\"%s\" is pallindrome\n", ch);
else
printf("\"%s\" is not pallindrome\n", ch);
getch();
return 0;
}

Probably problem with scanning numbers - C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Program not doing what it should - C
Hello,
Following program only read numbers from input and do stop when rull is violated, but 1 big problem is that it doesn't stop reading numbers and worse, don't print on screen what it should.
The code:
#include <stdio.h>
#include <string.h>
void SIFT(int x_arr[ ], int y_arr[]);
int main ()
{
int x[20] = {0} , y[20] = {0};
int m=0,temp=0,curr=0,i=0,j=0;
printf("Please enter your numbers now:\n\n");
/*enter numbers one by one. if x[i+1] value < x[i] value, err msg.
when user want to end the series he must enter '0' which means end of string (it wont included in x[]) */
while ( (scanf("%d",&temp) ) != '0' )
{
if (temp >= curr)
{
x[i] = temp;
curr = temp;
i++;
}
else
{
printf("The numbers are not at the right order !\n\nProgram will now terminate...\n\n");
}
}
SIFT(x,y);
for (i=0 ; y[i]=='0' ; i++) /*strlen(y) without ('0')'s includes*/
m++;
/*Prints m , y's organs*/
printf("\n\nm = %d",m);
printf("Y = ");
while (y[j]!='0')
{
printf ("%d ,",y[j]);
j++;
}
return 0;
}
void SIFT(int x_arr[ ], int y_arr[])
{
int i=0,j=0;
while (x_arr[i] != '0')
{
if (x_arr[i] == x_arr[i+1]) /*if current val. equals next val. -> jump dbl at x_arr*/
{
y_arr[j] = x_arr[i];
i+=2;
j++;
}
else
{
y_arr[j]=x_arr[i];
i++;
j++;
}
}
}
Please help me solve this problem...
thnx.
As a first hint, scanf returns the number of items read, so the condition (scanf("%d",&temp) ) != '0' will only be hit if you read 48 items (the ASCII value of 0). This isn't going to happen with that format specifier so that's why you've got the loop.

Resources