Home > Software design >  How do I make this accept user input in upper and lower case, and make this more secure
How do I make this accept user input in upper and lower case, and make this more secure

Time:12-13

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 ...

  1. fflush(stdin) is UB [as mentioned in top comments].
  2. The sms and message are "parallel" arrays. That is, indexed in the same way. They can be simplified by using a single struct array.
  3. replaceWord replicates the entire string for each single word/phrase replacement.
  4. The direct calls to replaceWord leak memory on each iteration.
  5. The strcpy code in main leaks memory allocated and returned by getMessage and getSMS.
  6. Using strstr has to rescan the original string a lot.
  7. 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.
  8. upper/lower case can be handled by the strcase* functions (e.g. strcasecmp instead of strcmp).

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.
  • Related