1 Востаннє редагувалося Ostapchuk (06.12.2015 14:06:44)

Тема: Переведення рядка в число

Усім привіт!  *YES*

Я трішки практикуюсь на С++, і вже давно морочу собі голову з однією задачею.

Потрібно ввести число, і стільки ж разів вивести повідомлення "hello world\n"
Але якщо користувач вводить наприклад:"Pyat" - то вивести повідомлення "Error"
Я все майже реалізував, але моя програма не проходить до кінця тестування, так як при введені "12abrakadabra"
Програма переводить цей рядок в число, тобто виходить 12, і програма виводить 12 повідомлень "hello world\n"
Хоча мало б виводити "Error", так як там є символи!

Ось код:

Прихований текст
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
using namespace std;
int main()
{
int i,k,lineint;
string line;
cin>>line;
    if( sscanf(line.c_str(),"%d",&k) != 1/*перевірка на вміст символів у рядку*/ ) { cout<<"Error\n";}
else
{
lineint = atoi(line.c_str());/*переведення у число*/
for(i=0;i<lineint;i++) {cout<<i/*відображення скільки повідомлень*/<<" hello world\n";}
}
system("pause");
return 0;
}

Все ніяк не можу розібратися до кінця з функцією sscanf  *DONT_KNOW*

2 Востаннє редагувалося Betterthanyou (06.12.2015 15:10:09)

Re: Переведення рядка в число

#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
using namespace std;
int main()
{
    char str[100];
    int i, k, lineint;
    string line;
    cin >> line;
    if (sscanf(line.c_str(), "%d%s", &k, &str) != 1/*перевірка на вміст символів у рядку*/) { cout << "Error\n"; }
    else
    {
        lineint = atoi(line.c_str());/*переведення у число*/
        for (i = 0; i<lineint; i++) { cout << i/*відображення скільки повідомлень*/ << " hello world\n"; }
    }
    system("pause");
    return 0;
}

отут є чудовий приклад роботи sscanf http://www.c-cpp.ru/content/sscanf

Подякували: Ostapchuk1

3 Востаннє редагувалося Itari (06.12.2015 16:27:38)

Re: Переведення рядка в число

    #include <iostream>
    #include <string>
    #include <cctype>
    #include <cstdlib>
    using namespace std;
    int main()
    {
    int i,k,lineint;
    string line;
int b=0
do{
        cin>>line;
        size_t e;
 try{
     i=stoi(s,&e);
     for(;i>0;i--)cout<<"Hello word ";
         b=1;
 } catch(invalid_argument& ia) {
    cout<<"Що це за непотріб? Вводь ще раз."<<endl;
 }
}while(!b)
       
    system("pause");
    return 0;
    }

Підійде?

Подякували: Ostapchuk1

4 Востаннє редагувалося -=ЮрА=- (06.12.2015 19:52:50)

Re: Переведення рядка в число

Ostapchuk, навіщо після сканфу ще раз конвертувати рядок? Ти робиш роботу по конвертації 2 рази(такий підхід дуже нераціональний - уяви якщо таких перетворень потрібно кілка мільйонів, тоді ти зробиш на один зайвий мільйон дій більше), це можно зроботи дуже просто, якщо перевіряти наступний за числом символ, якщо він \0 чи знак табуляції (пробіл \t \r та інші то рядок дійсно має число у конкретній позиції)

#include <ctype.h>//isspace
#include <string>
#include <iostream>
using namespace std;

int main(){
    string lines[] = {
            "12abrakadabra",
            "25",
            "2a"};
    size_t elem = 0;
    int    value= 0;
    char   delim= 0;
    for( elem = 0; elem < 3; elem++ )
    {
        if( !sscanf(lines[elem].c_str(), "%d%c", &(value = 0), &(delim = 0)) )
            cout<<"sscanf error"<<endl;
        else
        if( delim ? isspace(delim) : true )
            cout<<"value : "<<value<<endl;
        else
            cout<<"string is not contain pure number"<<endl;
    }
    return 0;
}

http://codepad.org/EteHPDpg

string is not contain pure number
value : 25
string is not contain pure number

Погодся це набагато зручніше та коротше за довжиною.

Подякували: Ostapchuk1

5

Re: Переведення рядка в число

Betterthanyou написав:
Прихований текст
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
using namespace std;
int main()
{
    char str[100];
    int i, k, lineint;
    string line;
    cin >> line;
    if (sscanf(line.c_str(), "%d%s", &k, &str) != 1/*перевірка на вміст символів у рядку*/) { cout << "Error\n"; }
    else
    {
        lineint = atoi(line.c_str());/*переведення у число*/
        for (i = 0; i<lineint; i++) { cout << i/*відображення скільки повідомлень*/ << " hello world\n"; }
    }
    system("pause");
    return 0;
}

отут є чудовий приклад роботи sscanf http://www.c-cpp.ru/content/sscanf

Дійсно, не до кінця зрозумів з нею, тепер проблема з "12abrakadabra" немає, але я почав відлагоджувати програму і побачив ще один баг, коли є пробіли в строці, програма просто не реагує.


Itari написав:
Прихований текст
    #include <iostream>
    #include <string>
    #include <cctype>
    #include <cstdlib>
    using namespace std;
    int main()
    {
    int i,k,lineint;
    string line;
int b=0
do{
        cin>>line;
        size_t e;
 try{
     i=stoi(s,&e);
     for(;i>0;i--)cout<<"Hello word ";
         b=1;
 } catch(invalid_argument& ia) {
    cout<<"Що це за непотріб? Вводь ще раз."<<endl;
 }
}while(!b)
       
    system("pause");
    return 0;
    }

Підійде?

Дивно, чомусь в мене компілятор майже на все жаліється, навіть з виправленими помилками у коді, але я й досі не зрозумів логіки вашого коду, вибачайте якщо щось не так, просто я ще практикуюсь у вивчені С++.

-=ЮрА=- написав:
Прихований текст

Ostapchuk, навіщо після сканфу ще раз конвертувати рядок? Ти робиш роботу по конвертації 2 рази(такий підхід дуже нераціональний - уяви якщо таких перетворень потрібно кілка мільйонів, тоді ти зробиш на один зайвий мільйон дій більше), це можно зроботи дуже просто, якщо перевіряти наступний за числом символ, якщо він \0 чи знак табуляції (пробіл \t \r та інші то рядок дійсно має число у конкретній позиції)

#include <ctype.h>//isspace
#include <string>
#include <iostream>
using namespace std;

int main(){
    string lines[] = {
            "12abrakadabra",
            "25",
            "2a"};
    size_t elem = 0;
    int    value= 0;
    char   delim= 0;
    for( elem = 0; elem < 3; elem++ )
    {
        if( !sscanf(lines[elem].c_str(), "%d%c", &(value = 0), &(delim = 0)) )
            cout<<"sscanf error"<<endl;
        else
        if( delim ? isspace(delim) : true )
            cout<<"value : "<<value<<endl;
        else
            cout<<"string is not contain pure number"<<endl;
    }
    return 0;
}

http://codepad.org/EteHPDpg

string is not contain pure number
value : 25
string is not contain pure number

Погодся це набагато зручніше та коротше за довжиною.

Та ж сама ситуація як з попереднім прикладом, щоб краще роз'яснити проблему, я прикріпив скріншот

Прихований текст

http://savepic.net/7472211.png

6

Re: Переведення рядка в число

Ostapchuk - що в цій обробці строк не так як ти хотів?
http://codepad.org/k0MNeGs1

value : 12
sscanf error
sscanf error

7

Re: Переведення рядка в число

В рядку присутні окрім числа інші нечислові символи, я так зрозумів, воно переводить до пробілу, а інше ігнорує, а мало б виводити Error

8 Востаннє редагувалося -=ЮрА=- (07.12.2015 19:45:15)

Re: Переведення рядка в число

В рядку присутні окрім числа інші нечислові символи, я так зрозумів, воно переводить до пробілу, а інше ігнорує, а мало б виводити Error

- символи йдуть після табулятору, тому рядок містить число, щоб здіснити перевірку залишку краще підключити всі переваги С++ та використати stringstream

#include <string>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
 
int main(){
    string lines[] = {
            "12 abrakadabra",
            "hello world",
            "hello world",
            ""};
    bool   flag;
    string text;
    vector<int> data;
    size_t elem = 0;
    size_t item = 0;
    size_t size = 0;
    int    value= 0;
    stringstream ss;
    stringstream sl;
    for( elem = 0; elem < 4; elem++ )
    {
        flag = false;
        data.clear();
        if( !lines[elem].size() )
            flag = true;
        else
        {
            ss.str(lines[elem]);
            while( ss >> text ){
                sl.str(text);
                if( flag = sl>>value )
                    data.push_back(value);
                sl.clear();
            }
            ss.clear();
        }
        if( !flag )
            cout<<"error";
        else
        if( !(size = data.size()) )
            cout<<"empty string";
        else
        for(item = 0; item < size; item++ )
            cout<<data[item]<<" ";
        cout<<endl;
    }
    cin.get();
    return 0;
}

http://codepad.org/7YDsmu46

error
error
error
empty string

Post's attachments

sscanf.png 30.37 kb, 191 downloads since 2015-12-07