0

I am trying to make a funtion which takes the pointer to a character array, its size and 1 as arguements.

#include<stdio.h>
#include<string.h>

#define FIRST_LINE 1
#define DONE 2
#define MORE_LINES 3
#define EXTRA 4

int a_fun(int, char *, size_t);

main()
{
char que[20];
int status=0;
status=a_fun(FIRST_LINE,que, sizeof(que));
fputs(que,stdout);

printf("\nStatus:\t %d\n",status);

return 0;
}


int a_fun(int lnum, char *str, size_t sz)
{

    char *temp, ch, *end="!exit";
    if(lnum==FIRST_LINE)
    {

        if (fgets (str, sz, stdin) == NULL)
        {
            printf("\nEntered nothing at all. (Type !exit to terminate)\n");
            return FIRST_LINE;
        }
        for(;(*str!='\0'||*end!='\0');str++,end++)
        {
            if(!*str) if(!*end) return DONE;
        }

        if(strlen(str)>=sz)
        {
            while((ch=getchar())!='\n'); //cleaning buffer
            return EXTRA;
        }
        return MORE_LINES;
    }
}

I want to quit inputting by entering "!exit" but I am not able to do that. I have tried to do it with if(strcmp(str,"!exit")==0) return DONE; and with if(str=="!exit") return DONE;
Finally I tried to compare both character by character, but all in vein. Please try to give me some solution.

To input more lines we can use a conditional block in a_fun(), so basically right now it's just one line input function and my problem is terminating input process in between (if it goes in a multi-line state).

If you could give me any suggestion about making this function more secure, besides my original problem, that would be appreciated because I will be using this function in my CGI code for my website.

Ashish Tomer
  • 55
  • 1
  • 8
  • in the code block beginning with: 'for(;(*str!='\0'||*end!='\0');str++,end++)' if the input string is greater than 5 characters, then 'end' will be pointing past the end of the literal "!EXIT" and reading those characters. This is undefined behaviour and can/will read to a seg fault event. – user3629249 Jan 11 '15 at 09:49
  • this line: 'if(strlen(str)>=sz)' can never be true because the fgets() would prevent that happening – user3629249 Jan 11 '15 at 09:51
  • the fgets() function also inputs the newline before terminating the string with a nul byte (assuming the string+newline+nul fits into 20 characters) so need to use something like: 'strcmp(str, "!exit\n" )' – user3629249 Jan 11 '15 at 09:55

2 Answers2

2
if(strcmp(str,"!exit")==0)

This will not work because fgets() adds a newline char at the end of the input and you have to carefully replace \n with \0 in-oder to perform the above check

Gopi
  • 19,784
  • 4
  • 24
  • 36
  • Thank you @Gopi. I get it. See I also have solved it (in the answer below). – Ashish Tomer Jan 11 '15 at 06:58
  • You helped me find the answer. I didn't know ``fgets()`` adds a '\n' in the end. I was thanking you. :) – Ashish Tomer Jan 11 '15 at 07:19
  • it is (practically) mandatory the a programmer knows ALL the details about each system function that they use in their code. a google search using something like: 'syntax for .... function in C' will (almost) always return one or more links to detailed descriptions of the function. – user3629249 Jan 11 '15 at 09:58
0

Thanks @Gopi now I have solved my problem:

        while(1)
        {
            if((*end=='\0')&&(*str=='\n')) return DONE;
            if((*end!=*str)||(*end=='\0')) break;
            end++;
            str++;
        }

Another solution is:

    char end[]={'!','e','x','i','t','\n'};
    if(strcmp(str,end)==0) return DONE;
Ashish Tomer
  • 55
  • 1
  • 8