2009-04-23 2 views
2

Я хотел спросить, есть ли способ ввода пустых строк в scanf, Я использую этот [^ \ n], чтобы ввести то, что всегда исключает новую строку. Это правильно, но создает много проблем как это, кажется, находится в входной buffer.what это лучший способ ввода строки .both получает и fgets создаём много проблем,Входная строка через scanf

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

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

ответ

0

Если все у вас возникли проблемы с этими пустыми строками, используйте 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; 
} 
+0

offset = DEFAULT_BUFFER * итерация - итерация; , если эта строка будет просто: offset = DEFAULT_BUFFER * итерация – mawia

+0

C переведет символ '\ n' в «% * [^ \ n]» на литеральную новую строку. Чтобы он работал лучше, вам нужно сменить косую черту: «% * [^ \\ n]». Вы можете объяснить приведенные выше строки .how% * [^ \\ n] будет работать лучше, чем% * [^ \\ n]? – mawia

+0

вы упомянули, что код будет тратить определенное количество байтов на каждую итерацию. Я не вижу таких потерь. Можете ли вы указать, где такой вид? – mawia

1

Гораздо лучший способом, чтобы прочитать строку ввода является

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

while(fgets(stdin, line, sizeof line) != NULL) 
{ 
    /* Filter out whitespace before checking tokens. */ 
} 
+0

Да, я пытаюсь использовать fgets, но это создавало какую-то тонкую проблему. Программа ждала и ждала когда-либо после первого входа может предложить, что может быть причиной и как ее преодолеть? Спасибо! – mawia

+0

Да, fgets() синхронно, он будет ждать полной строки ввода перед продолжением. Неясно, что вам нужен неблокирующий способ чтения ввода; это другой вопрос. :) – unwind

0

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

0

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

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

в вашей второй строке «это» следует заменить на «те charachters». Не так ли? bcz% * [^ \ n] будет игнорировать все символы, которые не будут уничтожены. также что вы подразумеваете под «каждым вызовом после первого, который ничего не будет читать». Это bcz хранения новой строки во входном буфере. PLZ объясняет. – mawia

0

Я думаю, что зсапЕ вы ищете это:

зсапЕ ("% [^ \ п]% * с", ЬиЕ);

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

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

Неблокирующая вход это нечто совсем другое.Вы можете использовать режим «cbreak» в Google. Но это конечная вещь unix-y, и если вы работаете в Windows, это, вероятно, не имеет смысла. X/Gtk/Qt будет иметь другие способы делать такие вещи.

Смежные вопросы