Спецификатор преобразования "% s" будет соответствовать непробельным символам.
#define QUOTE(s) #s
#define STR(s) QUOTE(s)
#ifndef BUFSIZE
# define BUFSIZE 255
#endif
char buf[BUFSIZE+1];
while (fscanf(fin, "%" STR(BUFSIZE) "s", buf)) {
/* buf holds next word. Todo:
+ allocate space for word
+ copy word to newly allocated space
+ add to linked list
*/
}
В качестве альтернативы strtok
можно использовать для токенизации (разбиения) строки на подстрокииспользуя набор символов (как массив символов), который вы укажете.Ваша система также может иметь strsep
, который предназначен для замены strtok
.И strtok
, и strsep
изменяют передаваемый массив, поэтому позаботьтесь о том, чтобы это не вызывало проблем с другими частями кода, которые обращаются к данным.strsep
не является потокобезопасным;если у вас есть несколько потоков, обращающихся к анализируемой строке, используйте strsep
или strtok_r
.
#ifndef BUFSIZE
# define BUFSIZE 256
#endif
const char separators[] = "\t\n\v\r\f !\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~";
char buf[BUFSIZE], *line, *word, *rest;
while (fgets(buf, BUFSIZE+1, fin)) {
rest = line = buf;
while ((word = strtok_r(line, separators, &rest))) {
/* Todo:
+ allocate space for word
+ copy word to newly allocated space
+ add to linked list
*/
line=rest;
}
}
, так как второй пример читает строку из файла за раз для strtok_r
для работыЕсли длина какой-либо строки файла превышает BUFSIZE-1, а символы BUFSIZE-1 st и BUFSIZE th в строке представляют собой обе буквы, во втором примере слова будут разбитыдва.Решением этой проблемы было бы создание потока буферизованной строки, чтобы при достижении конца буфера все, что осталось в буфере, смещалось вперед, а остальная часть буфера заполнялась дополнительными данными из файла (простобудьте осторожны со словами длиннее буфера, в производственном коде это потенциальная уязвимость безопасности, которая может привести к атакам типа «отказ в обслуживании».
Проблема со всеми вышеперечисленными функциями заключается в том, что они не обрабатывают нулевые символына входе.Если вы хотите проанализировать данные, которые могут содержать нулевые символы, вам нужно использовать нестандартную функцию, которая включает в себя написание вашей собственной.
Что касается эффективности, любой алгоритм, который вы используете, должен будет прочитатьиз файла (сложность O (n) и потребует ввода-вывода, что замедляет работу программы) и выделение памяти для хранения слов.Используете ли вы fscanf
, strtok
или какой-либо другой метод, сложность времени и пространства вряд ли будет сильно отличаться;единственное, что может, это то, сколько промежуточных буферов выделено.Лучший способ найти наиболее эффективную реализацию - попробовать пару и профилировать их.