Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > число в строку


Автор: Guest 22.5.2005, 18:09
Попалась такая задача: определить является строка числом или нет с условием, первый символ строки может быть '+'.
Вот, что я смог написать. Подскажите где ошибки, заранее спасибо.

Код

#include <string.h>
#include <stdio.h>
#include <ctype.h>

int main(){
   int i,j,y,number,dlina;
   char *temp[dlina],*cislo[dlina];
   char *a="123556";

   dlina=strlen(a);
   j=0;
   temp[dlina]=a;

        if(temp[0]=="-"){
                printf("4islo ne mozet byt otrecatel'nym\n");
                return 0;
        }
        if(!isdigit(temp[0])&&(temp[0]!="+"))
                printf("Eto ne 4islo\n");
        if(isdigit(temp[0]))
                cislo[j++]=temp[0];

        for(i=1;i<=dlina;i++){
                if(isdigit(temp[i]))
                        cislo[j++]=temp[i];
                else{
                        printf("%s Eto ne 4islo\n",a);
                        return 0;
                }
        }
        number=atoi(cislo);
        printf("number: %d\n",number);
}


Автор: Guest 22.5.2005, 18:18
10-я строчка лишняя(temp[dlina]=a;)

Код

#include <string.h>
#include <stdio.h>
#include <ctype.h>

int main(){
   int i,j,y,number,dlina;
   char *temp[dlina],*cislo[dlina];
   char *a="123556";

   dlina=strlen(a);
   j=0;
         if(temp[0]=="-"){
                printf("4islo ne mozet byt otrecatel'nym\n");
                return 0;
        }
        if(!isdigit(temp[0])&&(temp[0]!="+"))
                printf("Eto ne 4islo\n");
        if(isdigit(temp[0]))
                cislo[j++]=temp[0];

        for(i=1;i<=dlina;i++){
                if(isdigit(temp[i]))
                        cislo[j++]=temp[i];
                else{
                        printf("%s Eto ne 4islo\n",a);
                        return 0;
                }
        }
        number=atoi(cislo);
        printf("number: %d\n",number);
}

Автор: sergejzr 22.5.2005, 18:21
а atoi нельзя пользоваться?

Автор: En_t_end 22.5.2005, 18:29
sergej.z
Вероятно это зачетная прога smile

Автор: Guest 22.5.2005, 18:34
если в строке присутствует запятая или точка, то atoi откинет дробную часть..

Автор: sergejzr 22.5.2005, 18:37
Ну atof smile

Автор: sergejzr 22.5.2005, 19:39
я бы так решил:

Код

#include <stdio.h> //больше нафиг ничего не надо :)

bool isPsositiveNumber(char * check, char *number)
{
    if(*check=='+') //плюс ок. Берём строку со следующего символа
        check++;

        while((*check>'0'&&*check<'9')||*check=='.') //если буква число или точка, происходит копирование
        {
            *number++=*check++; //здесь копирование

        }
        
        return (*number++=*check++)==0; //копируем последний символ и проверяем, дошли ли до конца строки
}

int main()
{
    char *tst=new char[256];
    char *num="-12343546"; 

//Проверка на позитивный номер
    if(isPsositiveNumber(num,tst))
    {
        printf("%s is a number %s\n",num,tst); //Да! Распечатаем tst
    }
    else
    {
        printf("%s is NOT a number, tst not valid!!!\n",num); //Нет1! tst у нас не валидный.
    }
    return 0; //впринципе всё ок :)
}

Автор: Guest 24.5.2005, 08:53
Ну а вот более простой вариант, без лишних проверок и функций. smile

Код


#include <stdio.h>
#include <stdlib.h>

int main()
{
    char string[10]= {0};
    char *substring;
    double value = 0;
    
    printf("Vvedite chislo ");
    scanf("%s", string);
    value = strtod(string, &substring);
    printf("%f", value);
    system("pause");
    return 0;
}

Автор: sergejzr 24.5.2005, 13:15
Ув. Guest
во первых вы пользуетесь функцией strtod от которой мы вроде отказались,
во вторых Проверка на позитивное число отсутствует (и вообще на число)
в третьих отсутствует копирование правильного числа в строку
в четвёртых перевод в число - не нужная процедура, как видно из первого примера
в пятых Ваш пример будет примерно в 100 раз медленнее моего
в шестых(придирка smile ) хорошо написанная функция - всегда хорошо "лишних" не бывает smile


И чего в том варианте непростого? Комментары вроде тоже есть.
Ладно, напишу покороче

Код

#include <stdio.h> //больше нафиг ничего не надо :)

int main()
{
    char *number=new char[256]; //вспомогательный массив в который скопируется 
    char *result=number;//запомним указатель на ответ
    char *toCheck="+12343546"; //число которое надо проверить
    char *check=*toCheck=='+'?toCheck+1:toCheck; //плюс ок. Берём строку со следующего символа

    for(;((*check>'0'&&*check<'9')||*check=='.');*number++=*check++);//копируем пока символы валидные
    
    if(*number++=*check++)
      printf("%s is NOT a number, tst not valid!!!\n",toCheck); //Нет! toCheck у нас не валидный.
    else
      printf("%s is a number %s\n",toCheck,result); //Да! Распечатаем tst

    return 0; //впринципе всё ок :)
}

Автор: kleks 6.10.2005, 18:09
Попалась похожая задачка..., отсюда вопрос: а если в строке встречается пробел? Т.е как сделать так, что бы если я ввёл "321 321", то программа не приняла данную строчку за число!!! Заранее благодарен...

Автор: _hunter 6.10.2005, 18:13
проверить на наличие в строке пробелов -- strchr() ( или strstr() )

Автор: kleks 6.10.2005, 19:37
На сколько я понял, в вышеуказанном примере, я должен сделать буквально следующие:
Код

bool isPsositiveNumber(char * check, char *number)
{
    if(*check=='+') 
       check++;   
      char ch=' ';
        char *loc;
        loc=strchr(check,ch);
        while(*check>'0'&&*check<'9' && loc==NULL) 
        {
            *number++=*check++; 
        }
        
        return (*number++=*check++)==0; 
}

В чём ошибка?!

Автор: sergejzr 6.10.2005, 19:48
Цитата(kleks @ 6.10.2005, 17:09)
Попалась похожая задачка..., отсюда вопрос: а если в строке встречается пробел? Т.е как сделать так, что бы если я ввёл "321 321", то программа не приняла данную строчку за число!!! Заранее благодарен...

Она и так не примет.

Автор: kleks 6.10.2005, 20:09
Действительно..., а почему тогда если в гл. программе я сам ввожу заданную строку, например так:
Код

int main()
{
    char *tst=new char[256];
    char *num=new char[100]; 
    cin>>num;
    if(isPsositiveNumber(num,tst))
    {
        printf("%s is a number %s\n",num,tst); 
    }
    else
    {
        printf("%s is NOT a number, tst not valid!!!\n",num);
    return 0; 
}

То программа принемает это число (например "546 465")!!! Подскажите пожалуйста, что не так!!!

Автор: bel_nikita 6.10.2005, 20:10
Усложним задачку smile строка может быть шестнадцатиричным числом smile
Добавлено @ 20:14
kleks
Цитата
Попалась похожая задачка..., отсюда вопрос: а если в строке встречается пробел? Т.е как сделать так, что бы если я ввёл "321 321", то программа не приняла данную строчку за число!!! Заранее благодарен...

Код

BOOL _isdigit(const char* p) const
{
  for ( ; *p!=NULL; ++p ) { if (!isdigit(*p)) break; }
  return !*p;
}


Автор: kleks 6.10.2005, 20:36
Цитата(bel_nikita @ 6.10.2005, 20:10)
Код

BOOL _isdigit(const char* p) const
{
  for ( ; *p!=NULL; ++p ) { if (!isdigit(*p)) break; }
  return !*p;
}


Извините, но я не совсем понял, как это функция работает, я пытался её использовать, но результат всё равно тот же!!! могли объяснить?!

Автор: Void 6.10.2005, 20:48
Цитата(sergej @ 24.5.2005, 15:15)
    for(;((*check>'0'&&*check<'9')||*check=='.');*number++=*check++);

А что, "1234....4324...12" у нас теперь нормальное действительное число? smile
Код

bool is_number(const char *s) {
    if (*s == '+')
        ++s;
    if (!isdigit(*s))
        return false;
    while (isdigit(*s))
        s++;
    if (*s == '.')
        s++;
    while (isdigit(*s))
        s++;
    return !*s;    
}

Автор: bel_nikita 6.10.2005, 22:40
kleks
Цитата
Извините, но я не совсем понял, как это функция работает, я пытался её использовать, но результат всё равно тот же!!! могли объяснить?!

Код

#include <stdio.h>
#include <ctype.h>
#include <iosfwd>

using namespace std;

bool _isdigit(const char* p) 
{
  for ( ; *p!=NULL; ++p ) { if (!isdigit(*p)) break; }
  return !*p;
}

int main(int argc, char* argv[])
{
    printf("Hello World!\n");
  
  char *tst=new char[256];
  char num[100]={0}; 

  cin.getline(num,sizeof(num));

  if( _isdigit(num) )
  {
    printf("%s is a number %s\n",num); 
  }
  else
  {
    printf("%s is NOT a number, tst not valid!!!\n",num);
  }
  return 0; 
}

_isdigit(const char* p) - берет каждый символ и проверяет его: цифра или нет. Если нет, то возвращаем false

Автор: Helicopterr 6.10.2005, 23:04
возник обратный вопрос - как значение переменной int i поместить в char massive [n]?

Автор: bel_nikita 6.10.2005, 23:08
Код

int n  = 100;
int i = 123;

char massive [n];
sprintf(massive,"i=%d",i);

Автор: sergejzr 6.10.2005, 23:09
Цитата(Void @ 6.10.2005, 19:48)
что, "1234....4324...12" у нас теперь нормальное действительное число?

Ну да, надо прибить.
Код

int cnt=0;
for(;((*check>'0'&&*check<'9')||(*check=='.'&&!cnt++));*number++=*check++);//копируем пока символы валидные


Товарищи в задаче strtod, strtof, isdigit - функции библиотек, а ими пользоваться нельзя в этом случае иначе любую задачу X можно было бы решить:

#include <library_for_solving_X>
cout<<solve(X);

Ну а если пользоваться можно всем, то почему не strtod?


Цитата(kleks @ 6.10.2005, 19:09)
Действительно..., а почему тогда если в гл. программе я сам ввожу заданную строку, например так:

Это не функции проблема, а cin он пробелом разбивает на два числа. cin как то настраивается, но я сейчас не знаю таких тонкостей, на Си давно не прогал.
Добавлено @ 23:12
А, вот! cin.getline(num, длинна_num, '\n') поможет smile

Автор: Helicopterr 6.10.2005, 23:16
Цитата(bel_nikita @ 6.10.2005, 23:08)
Код

int n  = 100;
int i = 123;

char massive [n];
sprintf(massive,"i=%d",i);

ой я имел ввиду поместить на место n-го элемента с сохранением остальных. ( __int8 т.е. 0-9)

Автор: sergejzr 6.10.2005, 23:19
Вот пока полное решение:
Код

#include <iostream.h>//Только либа для ввода/ввывода
bool isPsositiveNumber(char * toCheck)
{
    char num[256]; //вспомогательный массив в который скопируется 
    char *number=num;
    char *result=number;//запомним указатель на ответ
    char *check=*toCheck=='+'?toCheck+1:toCheck; //плюс ок. Берём строку со следующего символа
    int cnt=0;
    for(;((*check>'0'&&*check<'9')||(*check=='.'&&!cnt++));*number++=*check++);//копируем пока символы валидные
    
    return (*number++=*check++)==0;
   
}
int main()
{
    int str_length=100;
        char *num=new char[str_length]; 
    while (true)
    {
         cin.getline(num,str_length,'\n');
     cout<<num<<" is "<<(isPsositiveNumber(num)?"":"NOT ")<<"a number"<<endl;
    }
    return 0; 
}

Добавлено @ 23:24
Цитата(Helicopterr @ 6.10.2005, 22:16)
ой я имел ввиду поместить на место n-го элемента с сохранением остальных. ( __int8 т.е. 0-9)


Код

#include <iostream.h>

int main()
{
    char number[256];
    cin.getline(number,256,'\n');//читаем число
    int insert=8;
    number[8]=insert+'0'; //теперь на восьмом месте восьмёрка
        return 0; 
}

Автор: bel_nikita 6.10.2005, 23:25
sergej.z
Цитата
Товарищи в задаче strtod, strtof, isdigit - функции библиотек, а ими пользоваться нельзя в этом случае иначе любую задачу X можно было бы решить
Как это нельзя? smile Это стандартные либы! И их нужно пользовать

Автор: sergejzr 6.10.2005, 23:29
Цитата(bel_nikita @ 6.10.2005, 22:25)
Как это нельзя? smile Это стандартные либы! И их нужно пользовать

Тогда смысл задания пропадает. потому что ответ={char *x="1234.44"; strtod((x),&x);}

Автор: Mayk 6.10.2005, 23:35
Хоть библиотеками пользоваться нельзя, но вот еще один метод(может string'ами можно). не претендует на скорость.
Код

bool isPositiveNumber(const char* n)
{
  return  strspn(n,"0123456789.+") == strlen(n)    //строка состоит только из цифр плюса и точки
                          && (*n == '+' || strchr(n, '+') == NULL ) //плюс либо в начале, либо его нет
                          && (strchr(n, '.') == strrchr(n,'.'))  //точка либо одна, либо её нет
}

smile (шучу конечно)

оффтоп отсюда
зы. а вообще запрещать юзать стд либы это неправильно. Это всё равно что учить изобретать велосипед - зачем? От этого никому легче не становится

Автор: sergejzr 6.10.2005, 23:36
Скажем так, ... неинтересно smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)