Если бы я делал то, что вы делаете, я бы делал это так :)
Я вижу, что многие люди получают одобрение (не здесь, я имею в виду на SO в целом) за рекомендацию людям использовать такие функции, как scanf()
и strtok()
, несмотря на то, что эти функции повсеместно считаются злыми, а не только потому, что они не являются потокобезопасными, а потому, что они изменяют свои аргументы таким образом, который трудно предсказать, и отладка которых является огромной головной болью.
Если вы malloc()ing
являетесь входным буфером для чтения из файла, всегда делайте его размером не менее 4 КБ — это наименьшая страница, которую ядро может предоставить вам в любом случае, поэтому, если вы не Делая миллион глупых маленьких 100-байтовых malloc()
, вы могли бы также — и не бойтесь выделять в 10 или 100 раз больше, если это облегчает жизнь.
Итак, для таких проблем, когда вы имеете дело с небольшими текстовыми файлами входных данных, вот что вы делаете:
malloc()
себе хороший большой буфер, достаточно большой, чтобы впихнуть в него весь файл ведрами и ведрами запаса
- откройте файл, проглотите всю эту чертову штуку с помощью
read()
и закройте его
- запишите, сколько байтов вы прочитали в
n_chars
(или что-то еще)
- сделать один проход через буфер и 1) заменить все новые строки на NUL и 2) записать начало каждой строки (происходит после новой строки!) в последовательные позиции в массиве
lines
(например, char **lines; lines=malloc(n_chars*sizeof(char *))
: не может быть больше строк, чем байт!)
- (необязательно) по мере продвижения перемещайте указатели начала строки, чтобы пропустить начальные пробелы
- (необязательно) по мере продвижения перезаписывайте завершающие пробелы с помощью NUL
- вести подсчет строк по ходу дела и сохранять его в
n_lines
- не забудьте
free()
этот буфер, когда закончите с ним
Итак, что у вас есть? У вас есть массив строк, которые являются строками вашего файла (необязательно с каждой строкой, лишенной начальных и конечных пробелов), и вы можете делать с ним все, что вам нравится.
Ну так что ты делаешь?
Пройдите через массив строк одну за другой, например:
for(i=0; i<n_lines; i++) {
if( '\0'==*lines[i] || '#' == *lines[i] )
continue;
// More code
}
Уже вы проигнорировали пустые строки и строки, начинающиеся с "#". Ваш конфигурационный файл теперь имеет комментарии!
long n;
int len;
for(i=0; i<n_lines; i++) {
if( '\0'==*lines[i] || '#' == *lines[i] )
continue;
// More code
len = strlen("insert");
if( 0== strncmp(lines[i], "insert", len) ) {
n = strtol(lines[i]+len+1, &endp, 10);
// error checking
tree_insert( (int)n );
continue;
}
len = strlen("delete");
if( 0== strncmp(lines[i], "delete", len) ) {
n = strtol(lines[i]+len+1, &endp, 10);
// error checking
tree_delete( (int)n );
}
}
Теперь вы, вероятно, видите 10 способов сделать этот код лучше. Я тоже. Как насчет структуры, содержащей ключевые слова и указатель на соответствующую функцию дерева?
Другие идеи? Выруби себя!
person
Emmet
schedule
14.03.2014
scanf
, а затем передать ввод в программу ... предполагая, что вы находитесь в старой доброй командной строке unixy! Маленькие программы вместе == большие результаты! - person Daniel Farrell   schedule 14.03.2014int n = fscanf (fptr, "%s %d", cmd, &num);
- person FoggyDay   schedule 14.03.2014_____
является допустимым идентификатором в C. - person jxh   schedule 14.03.2014