Проверьте возвращаемое значение из fscanf()
более тщательно; он вернет, например, 3, если он соответствует 3 полям. Возможно, вы захотите быть осторожнее с размерами различных строк, чтобы избежать переполнения буфера - однако, это, вероятно, тема для другого дня.
Возможность, которая меня поражает, заключается в том, что последняя вкладка в строке формата может быть лучше новой строки - но fscanf()
обычно довольно либерально относится к пробелам в строках и данных формата.
Эта упрощенная (но полная, работающая) версия вашего кода ведет себя более или менее разумно в MacOS X.
#include <stdio.h>
int main(void)
{
char b1[20], b2[20], b3[20], b4[20], b5[20];
while (fscanf(stdin,"%s\t%s\t%s\t%s\t%s\t", b1, b2, b3, b4, b5) == 5)
printf("%s\t%s\t%s\t%s\t%s\n", b1, b2, b3, b4, b5);
return 0;
}
Однако строка «k k k k k
» (5 одинарных букв, разделенных пробелами) трактуется как эквивалентная 5 разделенным табуляциям. Следовательно, проблема заключается в том, что в разделе §7.19.6.2 стандарта C указано:
Формат состоит из нуля или более директив: один или несколько пробелов
символы, обычный многобайтовый символ (ни%, ни пробел), либо
спецификация преобразования.
Вводимые пробельные символы (как указано в функции isspace) пропускаются, если только
спецификация включает спецификатор [, c или n.
Также, что касается спецификатора '% s', он говорит:
Соответствует последовательности символов без пробелов.
Для принудительного сопоставления реальных вкладок вам придется работать немного сложнее. Было бы намного проще прибегнуть к «чтению строки в буфер (fgets()
) и разделению ее вручную». Это также позволит вам ввести 5 слов в строку, и вы можете сгенерировать ошибку или предупреждение, если полей слишком мало или слишком много. С fscanf()
вы не можете этого сделать. Если вы наберете 8 слов в строке, первые пять будут прочитаны в первый раз, затем три оставшихся слова в строке плюс первые два в следующей и т. Д.