Подскажите как доделать прокрутку текста [c++]
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
Подскажите как доделать прокрутку текста [c++] - 2009-06-07 16:22:44.930000
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
Привет всем! Подскажите как доделать вот такую прогу: Открывается текстовый файл и по нажатию клавиши вниз текст сдвигается вниз на одну строчку, нужно доделать, чтобы по нажатию вверх текст сдвигался вверх так же на одну строчку. Преподаватель сказал можно доделать с помощью fseek, но что-то у меня не получается(: Может подскажите как это реализовать? Или ещё какие нибудь идеи подкинете. Вот начальный код программы: #include <stdio.h> #include <conio.h> #define LINECOUNTSYMBOL 80 #define PAGELINES 25 #define TRUE 1 #define FALSE 0 #define KEYESC 27 void typefile(const char *file) { FILE *in; int cfile, ckey; int lastenter = 0, needenter = PAGELINES; int seekline = 0; if ((in = fopen(file, "r")) == NULL) { printf("Can not open file %s", file); return; } do { for (;lastenter <= needenter;) { cfile = fgetc(in); if (cfile < 0 || cfile > 255 || feof(in)) needenter = lastenter; else { if (cfile == 10 || seekline >= LINECOUNTSYMBOL) { lastenter++; seekline = 0; putchar('\n'); } if (cfile != 10) { seekline++; putchar(cfile); } } } ckey = getch(); switch(ckey) { case KEYESC: break; case 224: ckey = getch(); if (ckey == 80) needenter++; else if (ckey == 72) { } break; } } while (ckey != KEYESC); void main(int argc, char * argv[]) { if (argc < 2) { printf("Count of arguments is small!\n"); return; } typefile(argv[1]); }
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 16:32:47.963333
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
Я особенно не разбирался, но: 1. for (;lastenter <= needenter;) Лучше заменить на while. 2. Внешний do зачем нужен? 3. quote:
чтобы по нажатию вверх текст сдвигался вверх так же на одну строчку. С потерей верхней строки?
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 16:38:42.460000
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
Да спасибо на while я уже заменил. По нажатию вверх одна нижняя строка пропадает, т.е. текст сдвигается вниз. do вроде так выполняется: Если полученный символ равен переводу строки или символов в строке >= 80, то увеличиваем счётчик перевода строки(lastenter) и обнуляем счётчик символов в строке(seekline) делаем перевод строки, а если полученный символ не равен \n то увеличиваем счётчик символов в строке
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 18:33:43.893333
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
quote:
2. Внешний do зачем нужен? Я стормозил. Открыл BC, с трудом вспомнил что к чему… Кое-что накропал, но код не работает по-человечески:
#include <stdio.h>
#include <conio.h>
#define LINECOUNTSYMBOL 80
#define PAGELINES 25
#define TRUE 1
#define FALSE 0
#define KEYESC 27
void typefile(const char *file)
{
FILE *in;
int cfile, ckey;
int lastenter = 0, needenter = PAGELINES;
int seekline = 0, lines_on_cur_page = 0;
long fpos = 0, tmp_fpos = -1;
if ((in = fopen(file, "r")) == NULL) {
printf("Can not open file %s", file);
return;
}
do {
while (lastenter < needenter) {
if (tmp_fpos < 0) fgetpos(in, &tmp_fpos);
cfile = fgetc(in);
if (cfile < 0 || cfile > 255 || feof(in)) needenter = lastenter;
else {
if (cfile == 10 || seekline >= LINECOUNTSYMBOL) {
lastenter++;
seekline = 0;
putchar('\n');
if (++lines_on_cur_page >= PAGELINES)
{
fpos = tmp_fpos;
tmp_fpos = -1;
lines_on_cur_page = 0;
}
}
if (cfile != 10) {
seekline++;
putchar(cfile);
}
}
}
ckey = getch();
switch(ckey) {
case KEYESC: break;
case 80: needenter++; break;
case 72:
clrscr();
lastenter = --needenter - PAGELINES;
needenter = (needenter < PAGELINES) ? PAGELINES : needenter;
lastenter = (lastenter < 0) ? 0 : lastenter;
// seekline--;
fsetpos(in, &fpos);
break;
/* case 224:
ckey = getch();
if (ckey == 80) needenter++;
else if (ckey == 72) {
}
break;*/
}
} while (ckey != KEYESC);
}
main()
{
clrscr();
/*if (argc < 2) {
printf("Count of arguments is small!\n");
return;
}*/
typefile("test.txt");
return 0;
}
Идея такая: 1. Нужно запомнить позицию в файле, которая представлена первым символом экрана, предшествующего текущему видимому. Это, как раз у меня, и не работает. Доделывать пока что не буду. Хочу кушать. 2. Затем нужно скорректировать needenter -= 1; 3. lastenter = needenter - PAGELINES; 4. Переместить файловый указатель.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 18:39:38.766666
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
Кстати: 1.) Переводы строки в DOS - это два символа: CRLF. У тебя учитывается только LF. Отсюда дополнительные сложности. 2.) Возможно сделать проще, во-первых, читая файл поблочно, а, во-вторых, загнав его куски в массив.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 18:56:07.696666
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
Спасибо огромное сейчас буду разбираться, что к чему. Идея насчёт массива очень хорошая, но вот реализовать её… Если через массив проще, может через него попробовать? Как понять считываем попблочно?
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 20:10:05.863333
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
quote:
Спасибо огромное сейчас буду разбираться, что к чему. Не благодари, т.к. по-человечески не работает. Я тебе только идею предложил, а решать подходит ли она и реализовывать тебе самому придётся, т.к. я не доделал. quote:
Идея насчёт массива очень хорошая, но вот реализовать её… Если через массив проще, может через него попробовать? По-моему, через массив проще. Но, в теории, через массив эффективнее. На практике, - не факт. quote:
Как понять считываем попблочно? В твоём случае, файл считывается посимвольно с fgetc(). Может считывать его блоками, используя fread()? Причём, читать блоки в динамически выделяемый массив…
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 20:26:02.500000
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
А если считывать построчно?
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 21:16:15.166666
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
Тоже вариант.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 22:09:06.443333
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
забыл спросить, что значат вот эти строчки: needenter = (needenter < PAGELINES) ? PAGELINES : needenter; lastenter = (lastenter < 0) ? 0 : lastenter;
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-07 22:16:27.163333
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
Если lastenter, needenter < 0, то они устанавливаются в нуль и PAGELINES, соответственно.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-08 20:56:42.300000
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
блин чё-то не получается, а послезавтра экзамен( может поможете реализовать идею с массивом
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-09 13:42:40.386666
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
quote:
блин чё-то не получается, а послезавтра экзамен( Прям, "в усмешке недоброй лицо бытия". :-/ Сделал косо, криво, идею с буфером полностью не реализовал. Но, вроде, работает.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <mem.h>
#define LINECOUNTSYMBOL 80
#define PAGELINES 25
#define TRUE 1
#define FALSE 0
#define KEYESC 27
//#define LINE_DELIMETER "\015\012"
// Page size in characters
const page_size = (LINECOUNTSYMBOL + 1)* PAGELINES;
typedef char TPageLines[PAGELINES][LINECOUNTSYMBOL + 1];
//---------------------------------------------------------------------------
// Bad. Pages und lines have variable size.
/*void goto_page(FILE* fs, const int page_number)
{
fseek(fs, page_number * page_size, SEEK_SET);
}
//---------------------------------------------------------------------------
void read_page(FILE* fs, char *page_buffer)
{
fread(page_buffer, page_size, 1, fs);
}
//---------------------------------------------------------------------------
long get_page_number(FILE *fs)
{
register long file_pos = ftell(fs);
return(((file_pos % page_size) > 0) ? file_pos / page_size + 1 :
file_pos / page_size);
}
//---------------------------------------------------------------------------
*/
//---------------------------------------------------------------------------
long get_file_size(FILE *fs)
{
long fpos = ftell(fs);
fseek(fs, 0, SEEK_END);
long fsize = ftell(fs);
fseek(fs, fpos, SEEK_SET);
return(fsize);
}
//---------------------------------------------------------------------------
int _fastcall myfgets(char *s, FILE *fs)
{
// I can't understood how works fucking fgets! fscanf works not in the
// manner, that need me (it's reads words, but not strings)
// VERY DIRTY! NEED OPTIMIZATIONS!
char buf[LINECOUNTSYMBOL + 1];
int buf_sz = LINECOUNTSYMBOL;
long cur_fpos = ftell(fs);
register int i = 0;
int retv = fread(buf, buf_sz - 1, 1, fs);
if (!retv)
{
// reading end of file
fseek(fs, cur_fpos, SEEK_SET);
long sz_end = get_file_size(fs) - cur_fpos;
buf_sz = sz_end;
retv = fread(buf, 1, sz_end, fs);
if ((retv < 0) || !retv) return(-1);
}
//buf[LINECOUNTSYMBOL + 1] = '\0';
//memcpy(s, buf, LINECOUNTSYMBOL + 1);
for (i = 0; i < buf_sz - 1; i++)
{
if ((buf[i] == 13) || (buf[i] == 10))
{
fseek(fs, cur_fpos + i + 2, SEEK_SET);
break;
}
if (s) s[i] = buf[i];
}
if (s) s[i] = '\0';
return(i);
}
//---------------------------------------------------------------------------
void _fastcall goto_page(FILE* fs, const int page_number)
{
}
//---------------------------------------------------------------------------
inline int _fastcall read_line(char *s, FILE *fs, int *line_number)
{
register int result = -1;
if ((result = myfgets(s, fs)) != -1) (*line_number)++;
return(result);
}
//---------------------------------------------------------------------------
int _fastcall goto_line(FILE *fs, const int line_number)
{
register int result = -1;
fseek(fs, 0, SEEK_SET);
for (register int i = 0; i < line_number; i++)
if ((result = myfgets(NULL, fs)) == -1) break;
return(result);
}
//---------------------------------------------------------------------------
int _fastcall read_page(FILE* fs, TPageLines page_buffer, int *global_line)
{
register int line_number = 0;
for (line_number = 0; line_number < PAGELINES; line_number++)
{
if (read_line(page_buffer[line_number], fs, global_line) == -1) break;
}
return(line_number);
}
//---------------------------------------------------------------------------
void typefile(const char *file)
{
FILE *in;
//char page_buffer[page_size];
TPageLines page_lines;
int cfile, ckey;
int lines_on_page = 0;
int line_in_file = 0;
long fpos = 0, tmp_fpos = -1;
if ((in = fopen(file, "r")) == NULL)
{
printf("Can not open file %s", file);
return;
}
lines_on_page = read_page(in, page_lines, &line_in_file);
for (int i = 0; i < lines_on_page; i++) puts(page_lines[i]);
do
{
ckey = getch();
switch(ckey)
{
case KEYESC: break;
case 80: // down
if (goto_line(in, line_in_file + 1) != -1)
{
memmove(page_lines, page_lines + LINECOUNTSYMBOL + 1,
lines_on_page - 1);
read_line(page_lines[lines_on_page - 1], in, &line_in_file);
// for (int i = 0; i < lines_on_page; i++) puts(page_lines[i]);
puts(page_lines[lines_on_page - 1]);
}
break;
case 72: // up
if (goto_line(in, line_in_file - 1 - PAGELINES) != -1)
{
line_in_file -= (1 + PAGELINES);
lines_on_page = read_page(in, page_lines, &line_in_file);
for (int i = 0; i < lines_on_page; i++) puts(page_lines[i]);
}
break;
/* case 224:
ckey = getch();
if (ckey == 80) needenter++;
else if (ckey == 72) {
}
break;*/
}
} while (ckey != KEYESC);
}
//---------------------------------------------------------------------------
main()
{
clrscr();
/*if (argc < 2) {
printf("Count of arguments is small!\n");
return;
}*/
typefile("test.txt");
return 0;
}
P.S.: Кстати, можешь зарегаться на форуме: artiomsoft.zx6.ru/phpbb? Форум свой охота, ну вот охота и всё тут. К тому же, здесь неудобно отвечать, у меня бытрый ответ нормально не работает, и, вообще, всё тормозит.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-09 17:15:26.260000
|
|
|
spartakdubna
Сообщений: 9
Оценки: 0
Присоединился: 2009-06-05 15:06:05.380000
|
Да ну ты мозг) спасибо. На форуме уже зарегался. Ничё что прога не оптимизирована, мне и такая сойдёт.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-09 17:28:02.696666
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
Мда, кстати, я заметил, что прокрутка вверх начинается только с третьей-четвёртой строки. И с отображением первой какая-то фигня. По идее, надо доделывать. P.S.: За регистрацию спасибо. А то там админ скучает. P.P.S.: На том форуме я часто бываю. Если не лень, отпиши, когда сдашь. Любопытно.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-13 01:39:28.136666
|
|
|
agdam
Сообщений: 29
Оценки: 0
Присоединился: 2008-07-03 02:17:47.360000
|
Извиняюсь может я не в тему,но мою тему удалили,решил сюда поставить.Ребята помогите доделать задачу-немогу понять где находится ошибка,я ещё плохо разбираюсь в С++,мне нужно решить задание.Заранее благодарен.
//подключить потоковую библиотеку ввода-вывода
#include <iostream>
//использовать стандартное пространство имен
using namespace std;
//начало функции main
int main()
{
//ввести значение a,b,c
double a,b,c;
cout << "Enter a:";
cin >> a;
cout << "Enter b:";
cin >> b;
cout << "Enter c:";
cin >> c;
//узнать равен ли а нулю
if(a==0)
{
//вывести решениe b,c
if(b==0 && c==0)
{
//вывеси сообщение x
cout << "Any x is solution";
}else
if(b==0 && c!=0)
{
//Если b равно нулю а c не равно нулю
cout << "x=0:";
}
else
}
x=-c/b;
cout << x << endl;
{
else
}
//вычислить дискриминант
double d=b*b-4*a*c;
if(d==0)
{
d=-b/(2*a);
cout << "d равно нулю." << endl;
}
else
{
x1=(-b - sgrt (d))/(2*a);
x2=(-b + sgrt (d))/(2*a);
cout << "d не равно нулю." << endl;
}
cout("x1=%f x2=%f");
}
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-13 11:02:27.210000
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
//подключить потоковую библиотеку ввода-вывода
#include <iostream.h>
#include <math.h>
//использовать стандартное пространство имен
//using namespace std;
//начало функции main
int main()
{
//ввести значение a,b,c
double a, b, c;
cout << "Enter a:";
cin >> a;
cout << "Enter b:";
cin >> b;
cout << "Enter c:";
cin >> c;
if(a == 0)
{
//вывести решениe b,c
if(b == 0 && c == 0)
{
cout << "Any x is solution";
}
else if(b == 0 && c != 0)
{
cout << "x = 0:";
}
else
{
double x = -c/b;
cout << x << endl;
}
} // a == 0
else
{
//вычислить дискриминант
double D = b*b - 4*a*c;
double x1, x2;
if (D == 0)
{
x1 = x2 = -b/(2*a);
cout << "D равно нулю." << endl;
}
else
{
x1 = (-b - sqrt(D)) / (2*a);
x2 = (-b + sqrt(D)) / (2*a);
cout << "D не равно нулю." << endl;
}
cout << "x1 = " << x1 << endl << "x2 = " << x2 << endl;
} // else if (a != 0
}
P.S.: Большая просьба зарегистрировать у меня на форуме: artiomsoft.zx6.ru/phpbb Хочется чтобы народу сколько-нибудь было.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-13 17:13:54.190000
|
|
|
_SaZ_
Сообщений: 4329
Оценки: 398
Присоединился: 2008-01-30 02:18:05.553333
|
А что за форум? Ты бы хоть имя себе нормальное купил :), всего 10 баксов в год стоит.
|
|
|
RE: Подскажите как доделать прокрутку текста [c++] - 2009-06-13 19:54:17.353333
|
|
|
Hateman
Сообщений: 62
Оценки: 0
Присоединился: 2009-06-06 20:22:22.040000
|
quote:
А что за форум? Ты бы хоть имя себе нормальное купил :), всего 10 баксов в год стоит. Я человек бедный. :-) Домен 2-го уровня у меня есть, но он нахаляву, хостер только HTML разрешает. Смысла сейчас покупать нет, т.к. пока что не известно пригодится ли. Форум изначально для поддержки софта, а так - на любую тематику. Мне ещё самому важно, чтобы народ приходил. Чтобы было с кем общаться. Так что, если зарегистрируешься, буду благодарен: artiomsoft.zx6.ru/phpbb .
|
|
|
|
|