Re: С++ чтение файла по словам

Kitry

Есть файл с текстом, нужно прочитать его по словам... Можно ли это сделать без посимвольного чтения, тк разделитель не является фиксированным. Программа в vs c++. Или аналогичный вопрос как читать строку по словам, тк чтение файла по строкам fgets

Serab

Неясно, почему не надо читать посимвольно, я бы читал посимвольно.
как именно нефиксирован разделитель?
Из строки — тоже неясно, в чем вопрос, запоминать, где закончилось предыдущее слово, пропускать все разделители, потом вытягивать все не-разделители, выдавать, поправлять указатель на конец последнего слова.

Kitry

Вопрос 1: можно ли это сделать или нельзя, если можно, то как? Посимвольно это сделать просто, но файл огромен, так что удобней работать считывая строки.

zorin29

Буферизацию чтения за тебя все равно проведет ОС, если это нормальная ОС. Так что посимвольно ты читаешь, или построчно - неважно.
Библиотечной функции "читать до разделителя" в C++ нет.

Kitry

Учи матчасть... strtok... Тема закрыта

okis

strtok это совсем не про файл

zorin29

Но, очевидно, топикстартеру подошла. Пойду учить матчасть. Точнее, наверно, телепат-часть.

Serab

как раз если файл огромен, то это аргумент за посимвольное считывание.

Devid

Библиотечной функции "читать до разделителя" в C++ нет.
А как же std::ifstream::getline ?

Werdna

Буферизацию чтения за тебя все равно проведет ОС, если это нормальная ОС. Так что посимвольно ты читаешь, или построчно - неважно.
Пипец как не важно. Чтение (read) — это системный вызов. Использовать надо буферизированное чтение (fread/fgets).
Топикстартер, используй fgets. Будешь получать построчно, если строки не пипец какие длинные (меньше чем твой буфер куда читаешь).

apl13

(\fileName ->IO.openFile fileName IO.ReadMode >>= IO.hGetContents >>= return . words)

:cool:

zorin29

Пипец как не важно. Чтение (read) — это системный вызов. Использовать надо буферизированное чтение (fread/fgets).
Ну про read ты первый заговорил, я вообще имел в виду нечто вроде fgetc для посимвольного чтения. Насколько мне известно, эти вызовы тоже буферизуются. Более того, я весьма надеюсь, что и read из файла делается с буферизацией.
Впрочем, ты прав, системные вызовы тоже тормозят исполнение, так что чтение больших кусков эффективнее чтения малых.
Но, по-моему, работающая программа лучше, чем неработающая, но быстрая.
Вот ты бы как сделал построчное чтение? Либо пришлось бы вводить ограничение на длину строк (и хорошо, если оно продиктовано задачей либо придеся обрабатывать ситуацию, когда очередное слово попало на границу буфера.
А если такую ситуацию все равно обрабатывать, то strtok применять не очень удобно. Тогда уж лучше читать сразу не строки, а буферы по 4 килобайта, такой себе буфер второго уровня для экономии системных вызовов.

zorin29

Вот рекомендует топикстартеру учить Хаскель. Тоже решение, да. Впрочем, его задачу это не решит, конечно.
Зато знает Хаскель, а это, как никак, 40-й самый популярный язык программирования, сразу после COBOL, D и Forth :)

Bibi

хаскеля на десктопе всяко больше, чем кобола

apl13

Зато знает Хаскель
FALSE

tokuchu

Вот ты бы как сделал построчное чтение?
mmap

ppplva

А если не влезет?

Werdna

Ну про read ты первый заговорил, я вообще имел в виду нечто вроде fgetc для посимвольного чтения. Насколько мне известно, эти вызовы тоже буферизуются. Более того, я весьма надеюсь, что и read из файла делается с буферизацией.
Очевидно, что нет. read — это системный вызов. То что он не чиркнет дизг — это не значит что он такой же быстрый как fgetc. Если же говорить о fgetc/fgets, то как-то глупо говорить о ОС. Это libc, от неё всё зависит.
Вот ты бы как сделал построчное чтение? Либо пришлось бы вводить ограничение на длину строк (и хорошо, если оно продиктовано задачей либо придеся обрабатывать ситуацию, когда очередное слово попало на границу буфера.

fgets.
Если в задаче возможны очень длинные строки, то пришлось бы писать что-то особенное, но разве это страшно? В любом случае там 10 строк кода делания fgets и += для std::string...

serega1604

>Очевидно, что нет. read — это системный вызов.
т.е. ты утверждаешь, что при каждом read идет обращение к hdd, а то что находится в cached игнорируется?

tokuchu

т.е. ты утверждаешь, что при каждом read идет обращение к hdd, а то что находится в cached игнорируется?
Он же написал:
То что он не чиркнет дизг — это не значит что он такой же быстрый как fgetc.

tokuchu

А если не влезет?
Что не влезет?
Размер файла больше адресного пространства имеется в виду?

ppplva

На моей машине каждый read обходится в 140ns, то есть меньше 7M/s, если читать по байту. Честно говоря, я думал будет сильно хуже.

ppplva

Да, ты не сможешь за-mmap-ить файл целиком, придется кусками, а значит - опять придется реализовывать ту логику которой так боится . И никакого преимущества над read.
На 32 битах с ASLR по-хорошему нельзя рассчитывать даже на 512M свободного адресного пространства подряд.

tokuchu

Да, ты не сможешь за-mmap-ить файл целиком, придется кусками, а значит - опять придется реализовывать ту логику которой так боится . И никакого преимущества над read.
На 32 битах с ASLR по-хорошему нельзя рассчитывать даже на 512M свободного адресного пространства подряд.
Ну это только если мы хотим работать с очень-очень большими файлами или на древних платформах. :)
Ну т.е. мы заранее не знаем, что там за задача. mmap может вполне сгодиться.

serega1604

>Он же написал:
действительно :o , не смог разобрать из-за произношения.

zorin29

хаскеля на десктопе всяко больше, чем кобола
Я просто посмотрел на TIOBE. Думаю, для таких малых процентов вполне возможна ошибка, и Хаскель популярнее Кобола :)

Werdna

т.е. ты утверждаешь, что при каждом read идет обращение к hdd, а то что находится в cached игнорируется?

Я скорее буду обратное утверждать, потому что сейчас любая ОС имеет кеш на уровне чтения секторов.
Но системный вызов никто не отменял. Или ты думаешь, что это дешевая операция?

Werdna

На моей машине каждый read обходится в 140ns, то есть меньше 7M/s, если читать по байту. Честно говоря, я думал будет сильно хуже.
А теперь почитай большими порциями, особенно повторно, и оцени насколько результат выше.

Maximilian

топикастеру нужна функция
stream& getline (char* s, streamsize n, char delim );

где delim - регулярка аля '#\s+#m'
долбоебизм какой-то получается...

Maximilian

Вот ты бы как сделал построчное чтение?
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[CHARACTER SET charset_name]
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
[IGNORE number LINES]
[(col_name_or_user_var,...)]
[SET col_name = expr,...]

но там можно только один символ после TERMINATED BY, чего я ну НИКАК не ожидал ( было бы логично сделать, чтобы эта команда умела читать и из бинарных файлов. Но нет :
"The LOAD DATA INFILE statement reads rows from a text file into a table at a very high speed. The file name must be given as a literal string.")
т.е. так вот нельзя:
TERMINATED BY '\n' OR TERMINATED BY '\n\r' OR TERMINATED BY '\r\n' , что в нашем случае подошло бы
ИМХО mysql получает -1 за эту недоделку

okis

Казалось бы, при чем здесь Лужков!
Оставить комментарий
Имя или ник:
Комментарий: