2013-05-18 2 views
0

Я создал функцию, которая преобразует число в его эквивалент в данной базе и печатает его в строку. Это выглядит безупречно, но дает абсурдные результаты. Приведенный ниже код должен перевести 100 на базовую 9 и дать «121».Интересная ошибка в указателе строки

#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 
void doldur(string *s,int u,int base){ 
    *s=""; 
    while(u!=0){ 
     *s=""+u%base+*s; 
     u/=base; 
    } 
    return; 
} 
int main() { 
    ofstream fout ("dualpal.out"); 
    ifstream fin ("dualpal.in"); 
    int i; 
    string hey; 
    doldur(&hey,100,9); 
    cout<<hey; 
    cin>>i; 
    return 0; 
} 

Но смешно, он печатает dualpal.outualpal.outdualpal.out. (Также дает другие интересные результаты для различных баз)

Где недостаток?

+1

'' '' не типа 'std :: string'. – chris

+0

Почему вы объявляете 'fout' и' fin', если вы никогда не используете их? – jwodder

+1

В частности, это важно в этой строке: '* s =" "+ u% base + * s;' – wjl

ответ

4

Вы увеличиваете указатель на пустую строку на u%base места, а затем используете его для построения std::string, который ищет нулевой терминатор. Это вызывает неопределенное поведение. Используйте std::string с летучей мыши:

*s = std::string() + ...; 

Далее, нет никакого преобразования из int в std::string. Используйте функцию как std::to_string:

*s = std::to_string(u%base) + *s; 

Первый операнд теперь бессмысленно, так что я удалил его. Наконец, все эти разыгрывания немного утомительны, нет? Я бы сделал один и вернул его:

std::string doldur(const std::string &s,int u,int base){ 
    std:string ret; 
    while(u!=0){ 
     ret = std::to_string(u%base) + ret; 
     u/=base; 
    } 
    return ret; 
} 

Не беспокойтесь о каких-либо убытках от потери. Или используйте ссылку и измените оригинал, если хотите:

void doldur(std::string &s,int u,int) { 
    s.clear(); 
    while(u!=0){ 
     s = std::to_string(u%base) + s; 
     u/=base; 
    } 
}