LINUX.ORG.RU

Ламаковский вопрос от безисходности


0

0

Уже 6 лет программлю на Си, думал что со строками умею работать, а тут глюк страшный, который поствил под смонение мои знания :(

Вообщем есть текстовый файлик состоящий из строк следущего типа Login:UserRole:KodFaculteta:UsedTime:

Пример: superdancer:1:022600:3600:

Написал простенькую программку которая парсит этот файл. #include <stdio.h>

int main() { FILE *in; in = fopen("/base/logs/iucs_stat/iucs_stat_2004-11-25", "rt"); int userRole; char kod_fak[256]; int usedTime; char name[256]; char str[256];

while(!feof(in)) { fscanf(in, "%s:%i:%s:%i:\n",&name, &userRole, &kod_fak, &usedTime); printf("%s\n",name); }

fclose(in); return 0; }

Так вот в пременной name у меня кладется вся строка а не только login, а в остальных переменный ваще бред! Знаю что ошибка какая-то ламаковская, но я уже столько вариантов перепробовал, что даже не знаю куда теперь копать!

anonymous

>Уже 6 лет программлю на Си

правда?

> fscanf(in, "%s:%i:%s:%i:\n",&name, &userRole, &kod_fak, &usedTime);

во-первых надо писать так

fscanf(in, "%s:%i:%s:%i:\n",name, &userRole, kod_fak, &usedTime);

во-вторых цитата из man fscanf:



s Matches a sequence of non-white-space characters; the next
pointer must be a pointer to char, and the array must be large
enough to accept all the sequence and the terminating NUL char-
acter. The input string stops at white space or at the maximum
field width, whichever occurs first

то есть чтение в строку остановиться только встретив пробел, а до тех пор...

так что вся строка в name и все правильно.

fghj ★★★★★
()

Вообще-то, sscanf так и должен работать. Можешь
воспользоваться вот таким примером:

int parselist(char * src, char * divider, char ** target, int maxsize) {
    char * xrc = strdup(src);
    char * ptr = xrc;
    char * tmp = NULL;
    int count = 0;

    while ((count<maxsize)&&((tmp=strstr(ptr,divider))!=NULL)) {
        tmp[0] = 0;
        target[count] = strdup(ptr);
        count++;
        ptr = tmp+strlen(divider);
    }

    target[count] = strdup(ptr);
    count++;

    free(xrc);
    return count;    
}

src - исходная строка, divider - разделитель полей, в т.ч. можно
использовать многосимвольный, target - массив, в который помещаются
ссылки на токены распасеной строки, maxsize - максимальное количество
токенов (де факто - размерность массива). После окончания обработки
не забудьте сделать free() для всех выделеных подстрок :-)

Использовать так:

char * lst[10];
for (i=0;i<10;i++) lst[i]=NULL;
tknt = parselist("F1:F2:F3:F4:F5",":",lst,10);
...
for (i=0;i<10;i++) if (lst[i]) free(lst[i]);

Ах да, пример распространяется под GPL со всеми вытекающими :-)

no-dashi ★★★★★
()
Ответ на: комментарий от fghj

Насчет амперсантов я знаю, просто я уже все варианты решил перепробовать. А насчет пробелов странно, раньше любым символом мог разделить!

Прийдется разделять пробелами, хотя повторюс раньше разделял с помощью двоеточия и все было ок.... Огромное спасибо

anonymous
()
Ответ на: комментарий от anonymous

%s действительно всегда читает символы до пробела.

Чтобы использовать другой разделитель (в данном случае -- двоеточие), надо использовать %[^:]

aa5779
()
Ответ на: комментарий от aa5779

aa5779 тебе подсказывает наиболее простое решение....
только мелкая поправка white-space characters это не только пробел,
там еще несколько символов входит....

anonymous
()
Ответ на: комментарий от anonymous

>aa5779 тебе подсказывает наиболее простое решение....

_Наиболее_ простое - это использовать для такой задачи _подходящий_ язык:-)

DonkeyHot ★★★★★
()
Ответ на: комментарий от DonkeyHot

Ага :)

an$ IFS=:; echo superdancer:1:022600:3600 | (read name role fuck time; echo $name-$role-$fuck-$time)
superdancer-1-022600-3600
an$ 

nobody ★★
()

>Уже 6 лет программлю на Си
Окончательное просветление в C++ наступает через 1.5-2 года, а уж в C гораздо раньше... Хреново ты програмишь.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.