2014-01-29 2 views
1

У меня есть поле, которое позволяет пробелу в текстовом файле, который является «цитированием». Возможно ли для fscanf прочитать поле с пробелами между вкладками, а затем показать его в printf? Citepage получает данные о отметке времени.Прочитать место на fscanf

Exemple .txt:

1[tab]AAAI[tab]Low-cost Outdoor Robot Platform for the Penn State Abington Mini Grand Challenge[tab]2005[tab]Robert Avanzato[tab]1[tab][espaco][tab]2013-03-07 16:49:1 

Мой текущий код:

while (!feof(fp)){ 
    fscanf(fp,"%d\t %19[^\t]\t %300[^\t]\t %d\t %100[^\t]\t %d\t %s\t %19[^\t]\n ",&artigos.id,artigos.sigla,artigos.titulo,&artigos.ano,artigos.autores,&artigos.citacoes,artigos.citepage,artigos.timestamp);   
    printf("\nid: %d ",artigos.id); 
    printf("\nsigla: %s ",artigos.sigla); 
    printf("\ntitulo: %s ",artigos.titulo); 
    printf("\nano: %d ",artigos.ano); 
    printf("\nautores: %s ",artigos.autores); 
    printf("\ncitacoes: %d ",artigos.citacoes); 
    printf("\ncitepage: %s ",artigos.citepage); 
    printf("\ntimestamp: %s ",artigos.timestamp); 
} 

ответ

0

fscanf не хорошо для separting вещи, основанные на вкладках или символы новой строки в отличие от пространства, поскольку он рассматривает все пробелы как то же - что-то, что нужно пропустить и проигнорировать. Всякий раз, когда у вас есть символ пробела в вашей строке формата (неважно, является ли это пробелом или вкладкой или новой строкой, все они делают то же самое), fscanf будет читать и отбрасывать пробелы, пока не найдет символ без пробелов. Так что в вашем случае, когда он попадает в \t после %d что читать citacoes, он будет пропускать в ввода следующие
\t \t, и следующий символ, который будет считан будет 2, так что это, где он начнет чтение для citepage ,

Теперь вы можете использовать %*1[\t] в строке формата, чтобы пропустить один символ табуляции (а не все пробелы), но сделать это грязно и подвержено ошибкам. Он также легко смешивается с неправильным вводом, что делает практически невозможным правильную диагностику пользователя о некорректном вводе. Но если вы хотите это сделать, замените все вкладки в строке формата %*1[\t] и удалите все пробелы, и они должны работать.

Лучше всего было бы прочитать всю строку в буфере (с помощью fgets), а затем использовать strsep, чтобы разделить ее на символы табуляции.

Также вы никогда не должны использовать feof - он не возвращает true до после, который вы безуспешно пытались прочитать за концом файла. Всегда проверяйте возвращаемое значение вызова fscanf или fgets.

+0

Является ли 'strsep' портативным? – dreamlax

0

Директивы '\t' и ' ' делают то же самое: пропустите любое пустое пространство. Чтобы использовать вкладку в качестве разделителя в scanf(), нужно использовать "%*1[\t]". strtok() или простой цикл может быть проще. См. @Chris Dodd

Предложите fgets()/sscanf() для лучшей обработки ошибок, особенно для этого сложного сканирования.
Кроме того, спецификатор формата для artigos.citepage нуждается в регулировке.

char buf[200]; 
if (fgets(buf, sizeof buf, fp) == NULL) Handle_EOFIOError(); 

// scan, but do not save 1 `\t` 
#define TF "*1[\t]" 
if (8 == sscanf(buf, 
    "%d"  TF "%19[^\t]" TF "%300[^\t]" TF "%d" TF 
    "%100[^\t]" TF "%d"  TF "%19[^\t]" TF "%19[^\t]", 
    &artigos.id, artigos.sigla, artigos.titulo, &artigos.ano, 
    artigos.autores, &artigos.citacoes, artigos.citepage, artigos.timestamp) { 
    Success(); 
} 
Смежные вопросы