Как читать из входных данных до тех пор, пока новая строка не будет найдена с помощью scanf ()?

#c #format #scanf

#c #формат #scanf

Вопрос:

Меня попросили выполнить работу на C, когда я должен читать из входных данных до тех пор, пока не останется пробел, а затем до тех пор, пока пользователь не нажмет enter. Если я сделаю это:

 scanf(" 00s  00s", a, b);
  

Это будет следовать 1-му правилу, но не 2-му.
Если я напишу:

Я умный

То, что я получаю, эквивалентно:
a = «I»;
b = «am»;
Но это должно быть:
a = «I»;
b = «я умный»;

Я уже пробовал:

 scanf(" 00s  00[^n]n", a, b);
  

и

 scanf(" 00s  00[^]", a, b);
  

В первом он ожидает, пока пользователь нажмет Ctrl D (для отправки EOF), а это не то, что я хочу.
Во 2-м он не будет компилироваться. В соответствии с компилятором:

предупреждение: не закрывается ‘]’ для формата ‘%[’

Есть хороший способ решить эту проблему?

Ответ №1:

scanf (и двоюродные братья) имеют одну немного странную особенность: пробелы в строке формата (большинство размещенных в) соответствуют произвольному количеству пробелов во входных данных. Как это бывает, по крайней мере, в языковом стандарте «C» по умолчанию новая строка классифицируется как пробел.

Это означает, что завершающий текст 'n' пытается сопоставить не только новую строку, но и любой последующий пробел. Это не будет считаться совпадением, пока вы не подадите сигнал об окончании ввода или не введете какой-либо небелый символ.

Один из способов справиться с этим — что-то вроде этого:

 scanf(" 00s  00[^n]%c", a, b, amp;c);

if (c=='n')
    // we read the whole line
else
    // the rest of the line was more than 2000 characters long. `c` contains a 
    // character from the input, and there's potentially more after that as well.
  

В зависимости от ситуации вы также можете захотеть проверить возвращаемое значение из scanf , которое сообщает вам количество успешных преобразований. В этом случае вы бы искали 3 , чтобы указать, что все преобразования были успешными.

Комментарии:

1. Это больше похоже на это! Теперь я понял. Я не знал эту часть о пустом символе из спецификации. Спасибо, это то, что мне действительно было нужно. Также спасибо за совет %c, он будет полезен для других целей.

2. «вне набора сканирования» недостаточно: % c и %n также являются исключениями

3. разве это не должно быть scanf(..., amp;c) ?

4. @HaxAddict1337: Упс, совершенно верно. Спасибо.

Ответ №2:

 scanf(" 00s  00[^n]", a, b);
  

Ответ №3:

используйте getchar и while, которые выглядят следующим образом

 while(x = getchar())
{   
    if(x == 'n'||x == '')
       do what you need when space or return is detected
    else
        mystring.append(x)
}
  

Извините, если я написал псевдокод, но я давно не работаю с языком C.

Комментарии:

1. Теперь я понял, что вы имели в виду. Все еще… Я думаю, что это немного похоже на усложнение того, что можно сделать проще. Тем не менее, это работает.

Ответ №4:

 #include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int main(void)
{
  int i = 0;
  char *a = (char *) malloc(sizeof(char) * 1024);
  while (1) {
    scanf("%c", amp;a[i]);
    if (a[i] == 'n') {
      break;
    }
    else {
      i  ;
    }
  }
  a[i] = '';
  i = 0;
  printf("n");
  while (a[i] != '') {
    printf("%c", a[i]);
    i  ;
  }
  free(a);
  getch();
  return 0;
}
  

Комментарии:

1. Почему такое сложное решение? Зачем выполнять так много операций, которые не являются необходимыми?

2. Да, Бруно, ты правильно высказался! В моем коде я выполняю посимвольное чтение, которое оправдывает вопрос «до», также есть хорошие оптимизированные способы. но для тех, кто начал кодировать. Мое решение будет хорошим примером того, как все работает.

3. @Bharadwaj_Turlapati Включать <conio.h> и использовать getch() на самом деле не очень приятно. Возможно, кто-то не разрабатывает или не обучается в Windows.

Ответ №5:

Я опоздал, но вы также можете попробовать этот подход.

 #include <stdio.h>
#include <stdlib.h>

int main() {
    int i=0, j=0, arr[100];
    char temp;
    while(scanf("%d%c", amp;arr[i], amp;temp)){
        i  ;
        if(temp=='n'){
            break;
        }
    }
    for(j=0; j<i; j  ) {
        printf("%d ", arr[j]);
    }

    return 0;
}
  

Ответ №6:

 #include <stdio.h>
int main()
{
    char a[5],b[10];
    scanf(" 00s  00[^n]s",a,b);
    printf("a=%s b=%s",a,b);
}
  

Просто напишите s вместо n 🙂

Комментарии:

1. Также s здесь не имеет смысла. %[^n] уже запрашивает все символы, кроме новой строки.

Ответ №7:

// увеличьте размер массива символов, если вы хотите использовать большее количество символов.

 #include <stdio.h>
int main()
{
    char s[10],s1[10];
    scanf("n");//imp for below statement to work
    scanf("%[^n]%c",s);//to take input till the you click enter
    scanf("%s",s1);//to take input till a space
    printf("%s",s);
    printf("%s",s1);
    return 0;
}
  

Комментарии:

1. В вашем примере вы игнорируете входные данные до новой строки, вы не выполняете проверки безопасности, которые s всегда будут n . Пожалуйста, смотрите Принятый ответ для примера ответа.