tags:

views:

488

answers:

5

i wanted to ask is there way to input blank in string through scanf, i am using this [^\n] to input what so ever excluding newline .is it correct ?but is creating lot of problem as it seems to be stored in the input buffer.what is the best way to input string .both gets and fgets are creating lot of problems,

        while(strcmp(buf,"quit"))
         { 
   scanf("%*[^\n]",buf);
   n=send(connected,buf,strlen(buf),0);
   if(n<0)
   {
   perror("send");
   printf("error sending");
   exit(1);
   }
   //printf("server has send\n");
   n=recv(connected,buf,100,0);
   if(n<0)
   {
   perror("recv");
   printf("error recieving");
   exit(1);
   }
   //printf("waiting to recieve something\n");
   buf[n]='\0';
   printf("client:%s\n",buf);
  }

this is creating infinite loop the same thing is repeated again and again.

+1  A: 

A far better way to read a line of input is

char line[128]; /* Or whatever. */

while(fgets(stdin, line, sizeof line) != NULL)
{
  /* Filter out whitespace before checking tokens. */
}
unwind
yeah i was trying fgets but it was creating some subtle problem.the programme was waiting and waiting for ever after first inputcan suggest what could be the reason and how to overcome it?Thanks!
mawia
Yeah, fgets() is synchronous, it will wait for a full line of input before continuing. It wasn't clear that you wanted a non-blocking way of reading input; that is a different question. :)
unwind
A: 

If all you are having trouble with is empty lines, use strcmp("\n", buffer) == 0.

The regexp you posted won't work very well because C will translate the '\n' char in "%*[^\n]" to a literal newline. To have it work better you need to scape the slash: "%*[^\\n]".

However, it seems the trouble is also with the reading, i recommend you use a better function for that.

I have used the following code before to read sequential lines of arbitrary size from a file.

Couple of notes, though:

  1. The returned buffer needs to be free()d after you are done with it
  2. The code wastes a couple of bytes every iteration, but this is not really noticeable unless BUFFER_SIZE very small in comparision to the length of the lines.

The code, however, guarantees that one full line will be read from the FILE * and it will end in '\n'.

/*
 * Initial size of the read buffer
 */
#define DEFAULT_BUFFER 1024

/*
 * Standard boolean type definition
 */
typedef enum{ false = 0, true = 1 }bool;

/*
 * Flags errors in pointer returning functions
 */
bool has_err = false;

/*
 * Reads the next line of text from file and returns it.
 * The line must be free()d afterwards.
 *
 * This function will segfault on binary data.
 */
char *readLine(FILE *file){
    char *buffer   = NULL;
    char *tmp_buf  = NULL;
    bool line_read = false;
    int  iteration = 0;
    int  offset    = 0;

    if(file == NULL){
        fprintf(stderr, "readLine: NULL file pointer passed!\n");
        has_err = true;

        return NULL;
    }

    while(!line_read){
        if((tmp_buf = malloc(DEFAULT_BUFFER)) == NULL){
            fprintf(stderr, "readLine: Unable to allocate temporary buffer!\n");
            if(buffer != NULL)
                free(buffer);
            has_err = true;

            return NULL;
        }

        if(fgets(tmp_buf, DEFAULT_BUFFER, file) == NULL){
            free(tmp_buf);

            break;
        }

        if(tmp_buf[strlen(tmp_buf) - 1] == '\n') /* we have an end of line */
            line_read = true;

        offset = DEFAULT_BUFFER * (iteration + 1);

        if((buffer = realloc(buffer, offset)) == NULL){
            fprintf(stderr, "readLine: Unable to reallocate buffer!\n");
            free(tmp_buf);
            has_err = true;

            return NULL;
        }

        offset = DEFAULT_BUFFER * iteration - iteration;

        if(memcpy(buffer + offset, tmp_buf, DEFAULT_BUFFER) == NULL){
            fprintf(stderr, "readLine: Cannot copy to buffer\n");
            free(tmp_buf);
            if(buffer != NULL)
                free(buffer);
            has_err = true;

            return NULL;
        }

        free(tmp_buf);
        iteration++;
    }

    return buffer;
}
dsm
offset = DEFAULT_BUFFER * iteration - iteration;should this line be simply: offset=DEFAULT_BUFFER *iteration
mawia
C will translate the '\n' char in "%*[^\n]" to a literal newline. To have it work better you need to scape the slash: "%*[^\\n]".can you explain the above lines of yours .how %*[^\\n] will work better than %*[^\\n]?
mawia
you mentioned that the code will waste certain amount of byte every iteration.i dont see any such wastage.can you point out where is such watage?
mawia
A: 

You can also use getline() if your development environment supports it

dmityugov
A: 

There are two problems with scanf("%*[^\n]",buf);:

  1. The asterisk in the specifier causes value to be scanned, but not stored.
  2. It scans up until the next newline character, but doesn't consume that character. That means every call after the first one will read nothing.
Dingo
in your second line 'that' should be replaced with 'those charachters'.is'nt so? bcz %*[^\n] will couse all the charachters to be skipped that is they will not be consumed.also what do you mean by "every call after the first one will read nothing".is it bcz of the storage of new line in the input buffer.PLZ explain.
mawia
A: 

I think the scanf you're looking for is:

scanf("%[^\n]%*c", buf);

The %[^\n] gets your string, the %*c ignores the newline.

But, this is literally what you get if you google "how not to read a string in c"

Non-blocking input is something else entirely. You might google "cbreak mode." But, that's a unix-y terminal-y thing, and if you're on Windows, that probably doesn't make sense. X/Gtk/Qt will have other ways of doing that sort of thing.

smcameron