Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ада и другие языки _ Задача по строкам

Автор: 3BePb 15.12.2007 18:43

Ребята, помогите, пожалуйста. Я не то, что не знаю как написать программу, а я не знаю даже как это выполнить вообще логически. Помогите, пожалуйста. Вот задача: "Дана строка символов, состоящая из букв, цифр, запятых, точек, знаков “+” и “-“. Выделить подстроку, которая соответствует записи вещественного числа с плавающей точкой." Заранее благодарен.

Автор: Ozzя 15.12.2007 18:59

1. Отсечь символы, не входящие в запись вещественного числа с плавающей точкой
В запись могут входить +(-), арабские цифры, e(E), точка.
2. Проверить правильность написания числа.
Как вариант - strtofloat.

Автор: volvo 15.12.2007 19:37

Цитата
Как вариант - strtofloat.
Если установлен Билдер... А если нет?

Автору: название компилятора приведи...

Автор: Гость 15.12.2007 20:15

У меня Microsft Visual C++ 6.0 ну или 2005

Автор: 3BePb 15.12.2007 20:18

Цитата(Гость @ 15.12.2007 15:15) *

У меня Microsft Visual C++ 6.0 ну или 2005

Это написал не гость, а автор

Автор: 3BePb 15.12.2007 21:16

Ну я в принципе написал прогу, но она работает только если в строке встречаются один раз символы + - 1 2 3 4 5 6 7 8 9 0 e E .. Подскажите, а как сделать так, чтобы она работала и при повторяющихся этих символах. Кстати, вот текст моей программы:

char st[30],a[]="+-1234567890eE.",c[30];
int i,j,k,b=0;
puts("Vvedite stroku");
gets(st);
k=strlen(st);
for(i=0;i<k;i++)
for(j=0;j<15;j++)
if (st[i]==a[j])
{
c[b]=st[i];
b++;
}
for(i=0;i<b;i++)
printf("%c",c[i]);

Автор: volvo 15.12.2007 21:19

Примеры ввода и соответствующего им вывода приведи... И еще... К примеру, в строке может содержаться представление двух (или еще большего количества) чисел, что тогда делать? Какое из них возвращать?

Автор: 3BePb 15.12.2007 23:47

Цитата(volvo @ 15.12.2007 16:19) *

Примеры ввода и соответствующего им вывода приведи... И еще... К примеру, в строке может содержаться представление двух (или еще большего количества) чисел, что тогда делать? Какое из них возвращать?


Например, мы вводим -abcd1.135e+8. А вывод должен быть 1.135e+8. Ну а моя прога выведет "-" и всё. Насчёт представления двух чисел, то такого ввода не допускается

Автор: volvo 16.12.2007 2:06

Ну, как убрать все лишнее спереди - есть интересная идея... Смотри: есть строка, из которой можно читать данные через sscanf()... Вот и читаем (вернее пытаемся прочесть) из нее число с плавающей точкой, запоминая саму строку, из которой читаем. Если не удалось - то строка не начинается с представления этого числа, смещаемся на один символ вправо, и пытаемся прочесть число снова... И так до тех пор, пока этого сделать не удастся (число будет прочитано, даже если ПОСЛЕ него будут лишние символы, главное - чтоб их не было ПЕРЕД ним)...

Перечитал... Выглядит ужасно. Понять вообще ничего невозможно... Поделюсь небольшим фрагментом кода:

...
char *s = "-abcd-1.135e+8++uu"; // Это исходная строка
double f = 0.0;
char buffer[128];

for(char *p = s; *p; p++) {
strcpy(buffer, p);
if((count = sscanf(p, "%lf", &f))) break;
}
...


После окончания работы данного фрагмента в buffer-е будет "-1.135e+8++uu", то есть, мы "отсекли все лишнее" спереди... Теперь задача другая - отсечь все лишнее, что есть ПОСЛЕ числа... Этого сделать махинациями с sscanf() не удастся, тут другой путь, о котором выше говорил Оззя:
Цитата
1. Отсечь символы, не входящие в запись вещественного числа с плавающей точкой
В запись могут входить +(-), арабские цифры, e(E), точка.
Попробуй сделать это самостоятельно...

Автор: 3BePb 16.12.2007 3:44

Цитата(volvo @ 15.12.2007 21:06) *


...
char *s = "-abcd-1.135e+8++uu"; // Это исходная строка
double f = 0.0;
char buffer[128];

for(char *p = s; *p; p++) {
strcpy(buffer, p);
if((count = sscanf(p, "%lf", &f))) break;
}
...




А что такое count, т.е. какую библиотеку надо подключить, чтобы оно работало

Автор: volvo 16.12.2007 4:09

count - это переменная:

int count = 0;

Автор: 3BePb 16.12.2007 17:17

А напиши, пожалуйста, комментраий к if'у, а то я никак не пойму, что мы в нём(if'е) делаем.

Автор: volvo 16.12.2007 17:40

Функция sscanf пытается считать из строки то, что задано в ее "форматной строке". В данном случае, задано чтение "%lf" - то есть числа типа double. Но ведь sscanf - это функция, она ж еще и значение возвращает. А вот возвращает она - сколько найдено в строке соответствий с тем, что просили найти... То есть, пока вещественное число не может быть прочитано (хотя и требовалось) - sscanf будет возвращать 0 и запишется этот 0 в переменную count. Условие if в С++ выполняется, если выражение стоЯщее в нем - ненулевое, то есть, пока count == 0 выхода из цикла не будет. А значит, будет опять отбрасывание очередного символа в начале строки и еще одна попытка sscanf-а прочесть вещественное число...

Теперь, допустим, что buffer на каком-то этапе стал равным "-1.135e+8++uu"... В этом случае sscanf считает одно число из него... И вернет единицу. Вот эта единица и заставит цикл прерваться (через break)...

Теперь понятнее?

Автор: 3BePb 16.12.2007 17:54

Ну про sscanf вроде бы понятно. А вот почему у меня прога не работает..? Ты не мог бы посмотреть. Вот текст моей проги:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
char st[49],a[]="+-1234567890eE.",c[30];
int i,j,k,l,b=0;
puts("Vvedite stroku");
gets(st);
k=strlen(st);
int count=0;
char *s=st;
double f=0.0;
char buffer[128];
for(char *p=s;*p;p++)
{
strcpy(buffer,p);
if (count==sscanf(p,"%lf",&f)) break;
}
l=strlen(buffer);
for(i=0;i<l;i++)
for(j=0;j<15;j++)
if (buffer[i]==a[j])
{
c[b]=buffer[i];
b++;
}
for(i=0;i<b;i++)
printf("%c",c[i]);
getch();
}

Запусти, может чё подправишь.

Автор: volvo 16.12.2007 18:06

Цитата
А вот почему у меня прога не работает..?
Работать-то она работает, только неправильно... Потому что если я поставил один знак "=", значит, нужен именно один, а не 2:
if (count==sscanf(p,"%lf",&f)) break;
Там нет сравнения. Там присваивание... Это во-первых...

А во-вторых, недостаточно просто убрать все, что не может быть в записи числа... Нужно смотреть, что УЖЕ БЫЛО и думать, может ли этот же символ быть еще раз... Вот, например, "+" или "-". Он может быть не сколько угодно раз. Но и не один-единственный. Может быть один раз, может быть 2 раза, и это будет правильная запись (скажем, -1.135e-8)... А вот "E" (или "е") может быть ровно один раз - второе вхождение этих символов уже ошибка...

Так что исправляй.

Автор: 3BePb 16.12.2007 18:19

А как

Цитата(volvo @ 16.12.2007 13:06) *
... смотреть, что УЖЕ БЫЛО и думать, может ли этот же символ быть еще раз...
Подскажи, пожалуйста

Автор: volvo 16.12.2007 18:25

Вот эта программа, к примеру, решает задачу (за исключением одного частного случая - попробуй подумать и понять, какого именно):

int main()
{

char *s = "-abcd-1.135e+8++uu";
double f = 0.0;
char buffer[128];
int count = 0;

for(char *p = s; *p; p++) {
strcpy(buffer, p);
if((count = sscanf(p, "%lf", &f))) break;
}

const char *allowed = "0123456789eE+-.";
bool has_point = false;
int plus_count = 0;

for(char *p = buffer; *p; p++) {
if(strchr(allowed, *p)) {

switch(*p) {
case '.':
if(has_point) *p = '\0';
else has_point = true;

break;

case '+': case '-':
if(plus_count > 1) *p = '\0';
else plus_count += 1;

break;
}
}
else *p = '\0';
}
printf("buffer = %s\nnumber = %g\n", buffer, f);
return 0;
}

Автор: 3BePb 16.12.2007 18:51

Я подумал и, кажется, понял, что за частный случай. Она не работает, когда в строке присутствуют ещё цифры, обозначающие, например, запись целого числа. Например: -1abcd23fgh-1.75e+3. Твоя программка возвращает -1. Если строку вводим -abcd23fgh-1.75e+3, то она вернёт 23. А как исправить это?

Автор: volvo 16.12.2007 19:06

Это не является частным случаем, о котором я говорил... Ты же сам сказал, что

Цитата
Насчёт представления двух чисел, то такого ввода не допускается
Что, по-твоему, 23 не представляет собой ВТОРОЕ число?

Автор: 3BePb 16.12.2007 19:10

Я имел в виду, что не допускается ввода в строке двух вещественных чисел с плавающей точкой.

Цитата(volvo @ 16.12.2007 14:06) *

Это не является частным случаем, о котором я говорил...


А про какой частный случай ты говорил???

Автор: volvo 16.12.2007 20:04

"abcdfgh1.75e+3+fff"
Что будет?