ввод строки через scanf - PullRequest
       37

ввод строки через scanf

2 голосов
/ 23 апреля 2009

я хотел спросить, есть ли способ ввода пробела в строке через scanf, Я использую этот [^ \ n] для ввода того, что когда-либо исключает символ новой строки. Это правильно? но это создает много проблем, поскольку кажется, что он хранится во входном буфере. Каков наилучший способ ввода строки. fgets создает много проблем,

        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);
        }

это создает бесконечный цикл, то же самое повторяется снова и снова.

Ответы [ 5 ]

1 голос
/ 23 апреля 2009

Гораздо лучший способ прочитать строку ввода -

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

while(fgets(stdin, line, sizeof line) != NULL)
{
  /* Filter out whitespace before checking tokens. */
}
0 голосов
/ 24 апреля 2009

Я думаю, что вы ищите scanf:

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

% [^ \ n] получает вашу строку,% * c игнорирует перевод строки.

Но это буквально то, что вы получаете, если вы Google "как не читать строку в c"

Неблокирующий ввод - это нечто совершенно другое. Вы могли бы Google "режим Cbreak". Но это Unix-Y Terminal-Y вещь, и если вы на Windows, это, вероятно, не имеет смысла. У X / Gtk / Qt будут другие способы делать подобные вещи.

0 голосов
/ 24 апреля 2009

Есть две проблемы с scanf("%*[^\n]",buf);:

  1. Звездочка в спецификаторе приводит к тому, что значение сканируется, но не сохраняется.
  2. Он просматривает до следующего символа новой строки, но не потребляет этот символ. Это означает, что каждый звонок после первого ничего не будет читать.
0 голосов
/ 23 апреля 2009

Вы также можете использовать getline () , если ваша среда разработки поддерживает это

0 голосов
/ 23 апреля 2009

Если все, с чем у вас проблемы - это пустые строки, используйте strcmp("\n", buffer) == 0.

Регулярное выражение, которое вы разместили, не будет работать очень хорошо, потому что C переведет символ '\n' в "%*[^\n]" в буквальный перевод строки. Чтобы она работала лучше, вам нужно пересечь косую черту: "%*[^\\n]".

Однако, похоже, проблема также в чтении, я рекомендую вам использовать для этого лучшую функцию.

Ранее я использовал следующий код для чтения последовательных строк произвольного размера из файла.

Пара замечаний:

  1. Возвращенный буфер должен быть free() d после того, как с ним покончено
  2. Код тратит пару байтов на каждую итерацию, но это не очень заметно, если BUFFER_SIZE не очень мало по сравнению с длиной строк.

Код, однако, гарантирует, что одна полная строка будет прочитана из FILE * и будет заканчиваться на '\ 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...