Вопрос легкий, на 5 минут, но я новичок. Как читать файл, чтоб по строкам было, как readln например? Заранее благодарен
Если речь идет про С, то ф-ии gets/fgets должны помочь. Если про ассемблер, то можно вызвать эти же ф-ии, либо написать их самому. В общем, телепатируйте язык, ОС. P.S. Чую, тема для студенческого раздела.
Можно с lodsw и проверить ax на значение. Можно с помощью 'scasw', поместив перед этим в значение в ax.
Вот, пытаюсь хотя бы первую строку получить. Код (Text): invoke lstrlen,pMapFile mov ecx,eax cld mov eax,0D0Ah lea edi,pMapFile repne scasw jnz k20 mov eax,edi invoke lstrcpyn,addr szBuffer512_2,pMapFile,eax invoke MessageBox,hwnd_dlg_Main,addr szBuffer512_2,0,0 k20: Вроде все так же, как и у Абеля: Код (Text): STRLEN EQU 15 ;Длина поля STRING STRING DB 'The time&is now' ... CLD MOV AL,'&' ;Искомый символ MOV CX,STRLEN ;Длина поля STRING LEA DI,STRING ;Адрес поля STRING REPNE SCASB ;Сканировать JNZ K20 ;Символ найден? DEC DI ;Да - уменьшить адрес MOV BYTE PTR[DI],20H ;Подставить пробел K20: RET Запускаю, открываю файл, выполняется тот самый код и судя по тому, что никакого сообщения нет, выходит на k20
Аа.. понятно. Исправил. Но в этом месте Код (Text): repne scasw jnz k20 он почему то вылетает на k20. Правильно ли то, что до этого?
Сишник читает из файла побайтово, сваливая таким образом всю буферизацию на ОС. Советую поступить также, т.к. скорость не нужна, но получится проще.
Это неверно. ReadFile/WriteFile всегда переходят в режим ядра, так что вызывать их для побайтного чтения в случае хоть сколько-нибудь значительного файла приведёт к очень значительным издержкам. В msvcrt есть буферизация, и размер буфера по умолчанию там 0x200 байт. Qasm Во-первых, если ax=0D0A, то в байтовом представлении байты идут в порядке 0A 0D. Во-вторых, repne scasw ищет ax в массиве слов. Строка - это не массив слов, а массив байт. Если, к примеру, строка состоит из одного символа 41 ('A'), после которого следует перевод строки (в стиле DOS/Win, 0D 0A), то repne scasw проверит позицию 0, потом позицию 2, потом позицию 4, но не промежуточные позиции, так что не найдёт ничего.
diamond У меня с этим всегда проблемы были Ну да, я об этом догадывался Magnum Огромное спасибо! Пара вопросов об этом коде: 1) там случайно вместо mov ecx, [BufSize] не должен стоять mov ecx, [BlockSize]? Просто я не уверен 2) BlockSizeWORD <- что сюда надо передавать? Я со строковыми операторами в ассемблере не знаком, поэтому такие немного странные вопросы 3) XP вылетает с ошибкой ("Не отправлять отчет"), там точно должен стоять ret 12? Я его поменял на просто ret и больше ошибок с XP не было. Но он уже неправильно определял строку. Вот как я вызывал: Код (Text): invoke CreateFileMapping,hFile,NULL,PAGE_READONLY,0,0,NULL mov hMapFile,eax invoke MapViewOfFile,hMapFile,FILE_MAP_READ,0,0,0 mov pMapFile,eax invoke lstrlen,pMapFile mov BufSize,eax invoke ReadStr,pMapFile,addr szBuffer512_2,1 ; последний параметр наугад invoke MessageBox,hwnd_dlg_Main,addr szBuffer512_2,0,0
Тот код я за 2 минуты накатал... Вот рабочий вариант. На входе: pSrc - начало входного буфера EndFile - конец входного буффера (в твоем случае pMapFile + FileSize. FileSize можно получить, воспользовавшись функцией GetFileSize) pDest - выходной буффер Код (Text): ReadStr proc pSrc:DWORD, EndFile:DWORD, pDest:DWORD pushad mov esi, [pSrc] mov edi, [pDest] mov ebx, [EndFile] read_str: cmp esi, ebx jz end_read movsb cmp word ptr [esi-1], 0A0Dh jnz read_str end_read: movsb mov dword ptr [esp+28], esi mov dword ptr [esp+20], edi popad ret ReadStr endp на выходе: еах - указатель на начало новой строки в файле edx - указатель на конец текущей строки в выходном буффере вызывать так: Код (Text): mov ecx, pMapFile add ecx, FileSize invoke ReadStr, pMapFile, ecx, pOutBuffer ;считываем первую строку invoke ReadStr, eax, ecx, edx ;считываем вторую строку invoke ReadStr, eax, ecx, edx ;считываем n-ую строку
Код (Text): invoke lstrlen,pMapFile mov BufSize,eax сие есть не верно, ибо маппинг не есть zero-terminated строка =))