Stuck with comparing Strings in C [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 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);

Related

infix to postfix converstion in C with multiple digits input

What I'm trying to obtain is a calculator that will take infix notation, ignore insignificant whitespace characters like " " or '#', then convert that infix notaion into postfix notation and do simple calculations like addition, subtraction etc. So far the code is taking input in infix notation trimming it in a way that ignores insignificant whitespace characters and outputs the postfix notation.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>;
#include <ctype.h>;
#define MAX_LENGTH 100
//Functions
void push(char x);
char pop();
void trimString(char string[], char newString[]);
void inputToRPN(char trimmedExp[], char rpnExp[]);
int calculateRPN(char rpnExp[]);
char stack[MAX_LENGTH];
char resStack[MAX_LENGTH];
int top = -1;
int resTop = -1;
int index = 0;
int main() {
int res;
char exp[MAX_LENGTH] = "10 +2";
char trimmedExpression[MAX_LENGTH];
char rpnExpression[MAX_LENGTH];
// Input commented out as per suggestion in comments
//printf("Enter expression : ");
//fgets(exp, 100, stdin);
printf("Infix expression: %s \n", exp);
trimString(exp, trimmedExpression);
printf("\n");
inputToRPN(trimmedExpression, rpnExpression);
res = calculateRPN(rpnExpression);
//printf("Result of calculation: %d", res);
return 0;
}
void push(char x) {
stack[++top] = x;
}
char pop() {
if (top == -1)
return -1;
else
return stack[top--];
}
int priority(char x) {
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
return 0;
}
void trimString(char string[], char newString[]) {
int i = 0, j = 0;
while (string[i] != '\0' && string[i] != 10) {
// Range of significant characters
if (string[i] >= '(' && string[i] <= '9') {
newString[j] = string[i];
i++, j++;
}
else {
i++;
}
}
newString[j] = 0;
}
void inputToRPN(char trimmedExp[], char rpnExp[]) {
char* e, x;
e = trimmedExp;
while (*e != '\0') {
// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
// Add to stack if is an open brace
else if (*e == '(')
push(*e);
// Add all operators to the expression until finding open braces
else if (*e == ')') {
while ((x = pop()) != '(') {
rpnExp[index] = x;
index++;
}
}
// If none of the above, that is an operator - check it's priority.
// If it's priority is less that that of the one on top of the stack add the operator from the top of the stack to the expression; untill it's priority is higher.
// At the end add current operator to the stack.
else {
while (priority(stack[top]) >= priority(*e)) {
rpnExp[index] = pop();
index++;
}
push(*e);
}
e++;
}
while (top != -1) {
rpnExp[index] = pop();
index++;
}
// Terminating character at the end of the string
rpnExp[index] = 0;
}
void pushRes(char x) {
printf("pushing: %c \n", x);
resStack[++resTop] = x;
}
char popRes() {
printf("poping \n");
if (resTop == -1)
return -1;
else
return resStack[resTop--];
}
int isValidOperator(char c) {
if (c == '/' || c == '*' || c == '+' || c == '-')
return 1;
else
return 0;
}
int calculateRPN(char rpnExp[]) {
// Doesnt do anything yet, just prints out the compiled reverse polish notation
char* c;
int result = 0;
c = rpnExp;
printf("Postfix expression: %s", rpnExp);
return result;
}
The problem I've stumbled upon is when the infix input has multiple digits say 10+2 the code will treat each digit individually. Therefore the whole expression will be invalid when calculating result. I'm almost certain the issue lies in this line of code:
// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
Despite that I've got no idea how should i treat multiple digits while adding them to the expression, since the input is in form of character and there can be N amount of digits that have coresponding ascii values which range from 0-9. Looking forward to your answears.
Edit: made it so the code compiles and the input is hard coded.
Okay, so thanks to Bodos suggestions I've fixed the issue. Adding one while loop in this section:
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
enabled me to add one character after every number (including the N digit ones).
Thanks to which I was later able to perform calculations in calculateRPN function that would eventually lead to correct answear.
The issue has been resolved.

variable char size without malloc in C [duplicate]

This question already has answers here:
Can array length in declaration be non-constant?
(3 answers)
Closed 2 years ago.
does char myStr[varLength] work in C?
I have the following (code here):
int isVMin(char c){
return c == 'a' ||
c == 'e' ||
c == 'i' ||
c == 'o' ||
c == 'u' ||
c == 'y';
}
int isNum(char c){
return c>='0' && c<='9';
}
int removeChars(char str[]){ // removes all vowels, returns the digits number
int slen = strlen(str);
//char* res = malloc(sizeof(char)*slen+1);
char res[slen + 1]; /// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< DOES IT WORK AS EXPECTED???
printf("\nthe initial is: '%s'\n", res);
int numCount = 0, j = 0;
for (int i = 0; i < slen; i++) {
if (isVMin(str[i]));
//str[i]= ' ';
else {
res[j++] = str[i];
if (isNum(str[i]))
numCount++;
}
}
res[j] = '\0';
printf("\nthe removed is: '%s'\n", res);
//str = res;
return numCount;
}
int main(){
char phrase[50];
gets(phrase);
int nb = removeChars(phrase);
printf("\nLa phrase '%s' contient %d digits", phrase, nb);
return 0;
}
The program compiles and work as expected. However I have doubts if this usage is legal in C...
char res[slen + 1]; /// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< DOES IT WORK AS EXPECTED???
This works starting in C '99.
You're kind of limited as to how big. A rule of thumb would be exceeding 8k is probably not recommended. Note that on Windows, if the whole stack exceeds 1mb, the program will crash. On modern Unix. the same thing happens at a larger limit.
You can't return it though. Just sayin'

How do I store an array in three different ones based on delimiters

I want to split an input array into three different ones based on a / as a delimiter.
I have tried the (probably the naive) approach of storing an input string into different arrays by using getchar and while to read in the characters into an array and using a counter to count how many times a / appears.
Based on this number I would use:
if (slashcounter == 0) {
destinationarray[i++] = c;
}
to store it into the proper array. full implementation below.
please note that I try to do this using only stdio.h
#include <stdio.h>
char c;
char replace[80], toBeReplaced[80], input[80], testInput[80];
int i = 0;
int slashcounter = 0;
int main(){
puts("Enter a line of text: ");
while (( c = getchar()) != '\n'){
if (c == '/') {
slashcounter++;
}
if (slashcounter == 0) {
replace[i++] = c;
}
else if (slashcounter == 1) {
toBeReplaced[i++] = c;
}
else if (slashcounter == 2) {
input[i++] = c;
}
}
//debug purpose
puts("The arrays have the following content\n");
puts("replace[]:\n");
puts(replace);
puts("\n");
puts("toBeReplaced[]:\n");
puts(toBeReplaced);
puts("\n");
puts("input[]:\n");
puts(input);
printf("Slashcounter = %d\n",slashcounter);
return 0;
Unfortunately, what happens is: that the first word i.e. the word before the first slash is stored correctly but the other two are empty.
What have I done wrong here
the current output with the input this/test/fails
Enter a line of text:
this/test/fails
The arrays have the following content
replace[]:
this
toBeReplaced[]:
input[]:
Slashcounter = 2
Program ended with exit code: 0
p.s. I would also like to ensure that the /s are not in the output array.
Thank you for your help.
You have two immediate problems in your code, first you miss to add a null character to end each sub string, second you never reset the index to 0 when you read a /
Other problems are you do not check if you will write out of the arrays, and you do not not manages the EOF
You also test the value of slashcounter all the time, this is quite expensive for nothing, you can have 3 loops or use a pointer to point to the array to fill etc
There is also no reason to use global variables, all of them can be local in main
Example with minimal changes :
#include <stdio.h>
int main(){
int c;
char replace[80], toBeReplaced[80], input[80];
int i = 0;
int slashcounter = 0;
puts("Enter a line of text: ");
while (( c = getchar()) != '\n') {
if (c == EOF) {
fprintf(stderr, "unexpected EOF");
return -1;
}
if (c == '/') {
if (slashcounter == 0) {
replace[i] = 0;
}
else if (slashcounter == 1) {
toBeReplaced[i] = 0;
}
else if (slashcounter == 2) {
input[i] = c;
}
i = 0;
slashcounter++;
}
else if (slashcounter == 0) {
if (i != (sizeof(replace) - 2))
replace[i++] = c;
}
else if (slashcounter == 1) {
if (i != (sizeof(toBeReplaced) - 2))
toBeReplaced[i++] = c;
}
else if (slashcounter == 2) {
if (i != (sizeof(input) - 2))
input[i++] = c;
}
}
if (slashcounter == 0) {
replace[i] = 0;
toBeReplaced[0] = 0;
input[0] = 0;
}
else if (slashcounter == 1) {
toBeReplaced[i] = 0;
input[0] = 0;
}
else if (slashcounter == 2) {
input[i] = 0;
}
//debug purpose
puts("The arrays have the following content\n");
puts("replace[]:\n");
puts(replace);
puts("\n");
puts("toBeReplaced[]:\n");
puts(toBeReplaced);
puts("\n");
puts("input[]:\n");
puts(input);
printf("Slashcounter = %d\n",slashcounter);
return 0;
}
Note I use an int for c to handle EOF and I removed the useless array testInput
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra s.c
pi#raspberrypi:/tmp $ ./a.out
Enter a line of text:
this/test/fails
The arrays have the following content
replace[]:
this
toBeReplaced[]:
test
input[]:
fails
Slashcounter = 2

There's a space when I strcpy a string into another string

I have a kind of logical assignment here in my class. So my question is when I try to strcpy() a string into another string, There's a (like space) in my new string. I don't know how to delete that, perhaps my mistake. Please help me, thank you.
This program let's you type whatever letters or symbol on your keyboard and try to capture it and count the symbol. Then, return it.
Here's my code in C
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#define N 25
typedef char string[N];
int main(int argc, char *argv[])
{
int i,j;
int jumlah[10];
string inputan;
string temp;
int counter;
//Init
for(i=0;i<10;i++) {
jumlah[i]=0;
}
for(i=0;i<10;i++) {
temp[i]='-';
}
for(i=0;i<10;i++) {
inputan[i]='-';
}
do {
system("cls");
printf("\nMasukan kalimat: ");fflush(stdin);gets(inputan);
if(strcmpi(inputan,"0")!=0) {
strcpy(temp,inputan);
}
getch();
}while(strcmpi(inputan,"0")!=0);
printf("Hasil Analisa:\n\n");
for(i=0;i<10;i++) {
if(temp[i]!='-') {
char c = temp[i];
for(j=0;j<10;j++) {
if(temp[j]!='-') {
if(c == temp[j])
counter+=1;
}
}
jumlah[i] = counter;
counter = 0;
}
}
for(i=0;i<10;i++) {
if(temp[i]!=' ' && temp[i]!='-' && temp) {
printf("\t%c terdapat %d\n",temp[i],jumlah[i]);
}
}
getch();
}
And here's my console result:
So that's make the program will show the space symbol and count it.
And if I can ask again, how to display only one char if there's a symbol again in another index that have same symbol. Thx, forgive me if my English is not fluent.
The space(s) showing up at the end of your printout are because the list of test conditions you include:
if(temp[i]!=' ' && temp[i]!='-' && temp)
May be missing some additional conditions that need to be excluded:
1) added additional test: test[i] != 0
2) changed temp[i] != ' ' to !isspace(temp[i]), which will test against all white space.
Once these are added:
if(!isspace(temp[i]) && temp[i]!='-' && temp && (temp[i] != 0))
The text entered is printed only down to the last non-whitespace character.
Code modifications:
I added some other minor modifications to the following code that allowed the code to be compiled in my environment. Because my modifications use functions that are part of the C standard libraries, this should compile for you as well.
Changes also include expanding for(...) loops to accommodate the array sizes you created, enabling input up to N-1 characters as opposed to only 10. Most of what I did includes commented explanations.
int main(int argc, char *argv[])
{
int i,j;
//int jumlah[10];
int jumlah[N]; // probably meant to use N here?
string inputan = {0};
string temp = {0};
int counter = 0;// initialize
for(i=0;i<N;i++) {
jumlah[i]=0;
}
for(i=0;i<N-1;i++) {
temp[i]='-';
}
for(i=0;i<N-1;i++) {
inputan[i]='-';
}
do {
//system("cls"); This is fine, just does not work in my environment, so commented.
//printf("\nMasukan kalimat: ");fflush(stdin);gets(inputan);
printf("\nPut Sentence (or \"0\" to process): ");fflush(stdin);gets(inputan);// clarified instructions.
if(stricmp(inputan,"0")!=0) { //strcmpi
strcpy(temp,inputan);
}
//getch(); this (or getchar()) is really not necessary here to support
// the flow of your application.
}while(stricmp(inputan,"0")!=0);
printf("Hasil Analisa:\n\n");
for(i=0;i<N;i++) { //replace 10 with N
if(temp[i]!='-') {
char c = temp[i];
for(j=0;j<N;j++) { //replace 10 with N
if(temp[j]!='-') {
if(c == temp[j])
//counter+=1;
counter++; // var++ equivalent var += 1
}
}
jumlah[i] = counter;
counter = 0;
}
}
for(i=0;i<N;i++) {
//if(temp[i]!=' ' && temp[i]!='-' && temp) { // only spaces ?
if(!isspace(temp[i]) && temp[i]!='-' && temp && (temp[i] != 0)) { // temp[i] != 0, and exclude all white space
printf("\t%c terdapat %d\n",temp[i],jumlah[i]);
}
}
getchar(); //orig getch() not standard
}
Addressing your question: how to display only one char if there's a symbol again in another index that have same symbol.
Displaying a list of the characters used, and the number of times used might be better handled in a separate function. The one below can be adapted to be called in your original main function by inserting the following lines:
char *res = letterCounter("this is the string");
printf(res);
free(res);
Just under your existing line: printf("Hasil Analisa:\n\n");
(i.e. replace all your code under that line down to the getch(); function;
char * letterCounter(const char *string)
{
int i, j;
int len = strlen(string);
char *dup = StrDup(string);
if(!dup) return NULL;
int viewableAscii = '~' - '!'; /// range of ASCII from ! to ~ (33 - 126)
char buf[20];
char * results = calloc(100*strlen(string), 1);//ensure enough room
if(!results) return NULL;
/// caps 'A' == 65, 'Z' == 90
/// lowr 'a' == 97, 'z' == 122
/// all visable printables: 33 - 126
unsigned char characterUsageCounter[viewableAscii];
memset(characterUsageCounter, 0,viewableAscii);
for(i=0;i<len;i++)
{
for(j=0;j<viewableAscii;j++)
{
if(dup[i] == 33 + j)
{
characterUsageCounter[j]++;
}
}
}
for(i=0;i<viewableAscii;i++)
{
if(characterUsageCounter[i] > 0)
{
if(characterUsageCounter[i] == 1) sprintf(buf, "%c occurs %d time\n", i+33, characterUsageCounter[i]);
else sprintf(buf, "%c occurs %d times\n", i+33, characterUsageCounter[i]);
strcat(results, buf);
}
}
return results;
}
For example, if the string "this is the string" were passed as the argument to that function, the following would be output:

Luhn Algorithm sometimes work sometimes fail [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 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;

Resources