this keeps on print all sms that contain similar letter.
need to run code regardless of upper and lower case
Every time user enters and sms, the code prints all sms related to the letter, of example if another sms has a 'a', it print that plus the original sms.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *
replaceWord(const char *string, const char *oldWord, const char *newWord)
{
char *result;
int i, cnt = 0;
int newWordlen = strlen(newWord);
int oldWordlen = strlen(oldWord);
for (i = 0; string[i] != '\0'; i ) {
if (strstr(&string[i], oldWord) == &string[i]) {
cnt ;
// Jumping to index after the old word.
i = oldWordlen - 1;
}
}
// Making new string of enough length
result = (char *) malloc(i cnt * (newWordlen - oldWordlen) 1);
i = 0;
while (*string) {
// compare the substring with the result
if (strstr(string, oldWord) == string) {
strcpy(&result[i], newWord);
i = newWordlen;
string = oldWordlen;
}
else
result[i ] = *string ;
}
result[i] = '\0';
return result;
}
char *
getMessage(char sms[25][5], char message[25][25], char *input)
{
int i = 0;
for (i = 0; i < 25; i ) {
if (strstr(input, sms[i]) != NULL) {
char *result = replaceWord(input, sms[i], message[i]);
input = result;
}
}
return input;
}
char *
getSMS(char sms[25][5], char message[25][25], char *input)
{
int i = 0;
for (i = 0; i < 30; i ) {
if (strstr(input, message[i]) != NULL) {
char *result = replaceWord(input, message[i], sms[i]);
input = result;
}
}
return input;
}
int
main(void)
{
char sms[25][5] = { "R", "OMG", "L8", "2DAY", "U", "2", "PLS", "PPL",
"GAS", "FTL", "GG", "WYA", "ETA", "WYD", "HBU", "WTM", "WYM", "LOL",
"L", "W", "TTYL", "SYL", "ILY", "BRB", "NRN" };
char message[25][25] = { "ARE", "OH MY GOD", "LATE", "TODAY", "YOU",
"TO", "PLEASE", "PEOPLE", "GREETINGS AND SALUTATIONS", "FOR THE LOSS",
"GOOD GAME", "WHERE YOU AT", "ESTAMATED TIME ARIVAL", "WHAT YOU DOING",
"HOW ABOUT YOU", "WHATS THE MOVE", "WHAT YOU MEAN", "LAUGH OUT LOUD",
"LOST", "WON", "TALK TO YOU LATER", "SEE YOU LATER", "I LOVE YOU",
"BE RIGHT BACK", "NOT RIGHT NOW" };
// int i=0;
int choice = 1;
char input[100];
while (choice != 3) {
printf("Please choose :\n"
"1: SMS to Message.\n"
"2: Message to SMS.\n"
"3:Exit\n");
scanf("%d", &choice);
fflush(stdin);
if (choice == 1) {
printf("Please give SMS :");
scanf("%[^\n]", input);
strcpy(input, getMessage(sms, message, input));
printf("Converting SMS to Message :%s\n", input);
}
else if (choice == 2) {
printf("Converting Message to SMS :\n");
scanf("\n%[^\n]", input);
strcpy(input, getSMS(sms, message, input));
printf("%s\n", input);
}
else if (choice == 3) {
printf("Program Ended.\n");
}
else {
printf("Invalid Choice.\n");
}
}
getchar();
}
Here is the output:
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
1
Please give SMS :OMG
Converting SMS to Message :OH MY GOD
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
1
Please give SMS :WYM
Converting SMS to Message :WONHAT YOU MEAN
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
1
Please give SMS :LOL
Converting SMS to Message :LOSTAUGH OUT LOSTOUD
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
CodePudding user response:
A few issues ...
fflush(stdin)
is UB [as mentioned in top comments].- The
sms
andmessage
are "parallel" arrays. That is, indexed in the same way. They can be simplified by using a singlestruct
array. replaceWord
replicates the entire string for each single word/phrase replacement.- The direct calls to
replaceWord
leak memory on each iteration. - The
strcpy
code inmain
leaks memory allocated and returned bygetMessage
andgetSMS
. - Using
strstr
has to rescan the original string a lot. - Easier/better to make a copy of the original string and proceed char-by-char, phrase-by-phrase. No need to
malloc
a result string with the temp copy. And,replaceWord
[and its complexity] isn't needed. - upper/lower case can be handled by the
strcase*
functions (e.g.strcasecmp
instead ofstrcmp
).
Here is the reworked code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
// SMS/Message conversion
#if 1
struct sms {
const char *sms; // SMS short string
const char *message; // message long string
int slen; // sms string length
int mlen; // message string length
};
#endif
#if 1
struct sms smslist[] = {
{ "R", "ARE" },
{ "OMG", "OH MY GOD" },
{ "L8", "LATE" },
{ "2DAY", "TODAY" },
{ "U", "YOU" },
{ "2", "TO" },
{ "PLS", "PLEASE" },
{ "PPL", "PEOPLE" },
{ "GAS", "GREETINGS AND SALUTATIONS" },
{ "FTL", "FOR THE LOSS" },
{ "GG", "GOOD GAME" },
{ "WYA", "WHERE YOU AT" },
{ "ETA", "ESTAMATED TIME ARIVAL" },
{ "WYD", "WHAT YOU DOING" },
{ "HBU", "HOW ABOUT YOU" },
{ "WTM", "WHATS THE MOVE" },
{ "WYM", "WHAT YOU MEAN" },
{ "LOL", "LAUGH OUT LOUD" },
{ "L", "LOST" },
{ "W", "WON" },
{ "TTYL", "TALK TO YOU LATER" },
{ "SYL", "SEE YOU LATER" },
{ "ILY", "I LOVE YOU" },
{ "BRB", "BE RIGHT BACK" },
{ "NRN", "NOT RIGHT NOW" },
// end of list
{ NULL, NULL }
};
#endif
int
haseos(const char *eos)
{
int match;
switch (*eos) {
case 0:
// fall through
case ' ':
match = 1;
break;
default:
match = 0;
break;
}
return match;
}
void
getMessage(const struct sms *arr, char *out)
{
char buf[1000];
// copy the argument buffer
char *inp = buf;
strcpy(inp,out);
*out = 0;
while (*inp != 0) {
int match = 0;
// try for match on any/all SMS strings
for (const struct sms *cur = arr; cur->sms != NULL; cur) {
if (strncasecmp(inp,cur->sms,cur->slen) != 0)
continue;
// ensure the string has a delimiter after it
match = haseos(inp cur->slen);
// copy over replacement string and advance input/output pointers
if (match) {
strcpy(out,cur->message);
out = cur->mlen;
inp = cur->slen;
break;
}
}
// ordinary char
if (! match)
*out = *inp ;
}
// add final EOS terminator
*out = 0;
}
void
getSMS(const struct sms *arr, char *out)
{
char buf[1000];
// copy the argument buffer
char *inp = buf;
strcpy(inp,out);
*out = 0;
while (*inp != 0) {
int match = 0;
// try for match on any/all message strings
for (const struct sms *cur = arr; cur->sms != NULL; cur) {
if (strncasecmp(inp,cur->message,cur->mlen) != 0)
continue;
// ensure the string has a delimiter after it
match = haseos(inp cur->mlen);
// copy over replacement string and advance input/output pointers
if (match) {
strcpy(out,cur->message);
out = cur->slen;
inp = cur->mlen;
break;
}
}
// ordinary char
if (! match)
*out = *inp ;
}
// add final EOS terminator
*out = 0;
}
FILE *fin;
#define ASKSTR(_prompt,_str) \
askstr(_prompt,_str,sizeof(_str))
void
askstr(const char *prompt,char *buf,size_t buflen)
{
static int fileflg = -1;
if (fileflg < 0) {
struct termios tio;
fileflg = tcgetattr(fileno(fin),&tio) < 0;
}
printf("%s",prompt);
if (prompt[strlen(prompt) - 1] != '\n')
printf(": ");
fflush(stdout);
if (fgets(buf,buflen,fin) == NULL)
exit(7);
if (fileflg)
fputs(buf,stdout);
// strip newline
buf[strcspn(buf,"\n")] = 0;
}
int
asknum(const char *prompt)
{
char *cp;
char buf[100];
int ret = -1;
ASKSTR(prompt,buf);
do {
errno = 0;
int num = strtol(buf,&cp,10);
if (errno)
break;
if (*cp == 0)
ret = num;
} while (0);
return ret;
}
int
main(int argc,char **argv)
{
#if 0
const char **sms = { "R", "OMG", "L8", "2DAY", "U", "2", "PLS", "PPL",
"GAS", "FTL", "GG", "WYA", "ETA", "WYD", "HBU", "WTM", "WYM", "LOL",
"L", "W", "TTYL", "SYL", "ILY", "BRB", "NRN", NULL };
const char **message = { "ARE", "OH MY GOD", "LATE", "TODAY", "YOU",
"TO", "PLEASE", "PEOPLE", "GREETINGS AND SALUTATIONS", "FOR THE LOSS",
"GOOD GAME", "WHERE YOU AT", "ESTAMATED TIME ARIVAL", "WHAT YOU DOING",
"HOW ABOUT YOU", "WHATS THE MOVE", "WHAT YOU MEAN", "LAUGH OUT LOUD",
"LOST", "WON", "TALK TO YOU LATER", "SEE YOU LATER", "I LOVE YOU",
"BE RIGHT BACK", "NOT RIGHT NOW", NULL };
#endif
// for debug input:
#if 1
if (argc == 2)
fin = fopen(argv[1],"r");
else
fin = stdin;
if (fin == NULL) {
perror(argv[1]);
exit(1);
}
#endif
// for speed, compute string lengths
#if 1
for (struct sms *cur = smslist; cur->sms != NULL; cur) {
cur->slen = strlen(cur->sms);
cur->mlen = strlen(cur->message);
}
#endif
// int i=0;
int choice = 1;
char input[1000];
while (choice != 3) {
#if 0
printf("Please choose :\n"
"1: SMS to Message.\n"
"2: Message to SMS.\n"
"3:Exit\n");
scanf("%d", &choice);
fflush(stdin);
#else
choice = asknum("Please choose :\n"
"1: SMS to Message.\n"
"2: Message to SMS.\n"
"3:Exit\n");
#endif
switch (choice) {
case 1:
ASKSTR("Please give SMS",input);
#if 0
strcpy(input, getMessage(sms, message, input));
#else
getMessage(smslist, input);
#endif
printf("Converting SMS to Message :%s\n", input);
break;
case 2:
ASKSTR("Converting Message to SMS",input);
#if 0
strcpy(input, getSMS(sms, message, input));
#else
getSMS(smslist, input);
#endif
printf("%s\n", input);
break;
case 3:
printf("Program Ended.\n");
break;
default:
printf("Invalid Choice.\n");
break;
}
}
fclose(fin);
}
In the code above, I've used cpp
conditionals to denote old vs. new code:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
Note: this can be cleaned up by running the file through unifdef -k
Here is the sample input I used to test (per your example):
1
OMG
1
WYM
1
LOL
3
Here is the program output:
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
1
Please give SMS: OMG
Converting SMS to Message :OH MY GOD
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
1
Please give SMS: WYM
Converting SMS to Message :WHAT YOU MEAN
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
1
Please give SMS: LOL
Converting SMS to Message :LAUGH OUT LOUD
Please choose :
1: SMS to Message.
2: Message to SMS.
3:Exit
3
Program Ended.