перетворити рядок в ціле число в c ++ без втрати провідних нулів

привіт я маю проблему з перетворенням рядка чисел у ціле число. проблема полягає в тому, що, використовуючи atoi() для перетворення рядка в ціле, я втрачу провідні нулі. Чи можете ви, будь ласка, сказати мені спосіб це зробити, не втрачаючи провідних нулів?

#include 
#include 
#include 
#include 


using namespace std;

struct Book{
    int id;
    string title;
};

struct Author{
    string firstName; 
    string lastName;
};

Author authorInfo[200];
Book bookInfo[200];

void load ( void )
{

    int count = 0;
    string temp;

    ifstream fin;
    fin.open("myfile.txt");

    if (!fin.is_open())
    {
        cout << "Unable to open myfile.txt file\n";
        exit(1);
    }

    while (fin.good())
    {   
        getline(fin, temp, '#');
        bookInfo[count].id = atoi(temp.c_str());
        getline(fin, bookInfo[count].title, '#');
        getline(fin, authorInfo[count].firstName, '#');
        getline(fin, authorInfo[count].lastName, '#');
        count++;
    }

    fin.close(); 
}
2
@Panagiotis: Ви знаєте, скільки цифр потрібно на основі temp.length() . Збережіть цю довжину десь (наприклад, надішліть Book нову змінну-члену id_len ). Або просто просто збережіть ідентифікатор як рядок, а не ціле число.
додано Автор dreamlax, джерело
Цілі цифри не зберігають провідних нулів, як такі. Вони лише зберігають номер. Ви хочете відформатувати вихід з провідними нулями. Ви, ймовірно, також хочете розглянути питання про використання іншого, ніж atoi , оскільки він не може розрізняти 0 і помилку.
додано Автор chris, джерело
Я налаштовував назву, щоб відповідати на запитання. Для простого перетворення в int див.
додано Автор John Carter, джерело
як це зробити, якщо я не знаю, чи і скільки нулів призводить кожного разу?
додано Автор Panagiotis, джерело

7 Відповіді

Ціле число не має провідних нулів. Або, можливо, правильніше, він має між нулем і нескінченним їх числом. Номери 42, 042 та 000000042 (за винятком вихідного коду, де провідний 0 вказує на іншу базу) - це всі сорок два.

Якщо ви хочете зберегти провідні нулі, залиште його як рядок або зберігайте дещо відомості про те, наскільки великий початковий рядок. Щось подібне було б гарним початком:

#include 
#include 
#include 
#include 
#include 

int main (void) {
   //Test data.

    const char *sval = "0042";

   //Get original size.

    int size = strlen (sval);

   //Convert to int (without leading 0s).
   //strtol would be better for detecting bad numbers.

    int ival = atoi (sval);

   //Output details.

    std::cout << sval << " has size of " << size << ".\n";
    std::cout << "Integer value is " << ival << ".\n";
    std::cout << "Recovered value is " << std::setw(size)
        << std::setfill('0') << ival << ".\n";

    return 0;
}

які виходи:

0042 has size of 4.
Integer value is 42.
Recovered value is 0042.
3
додано

Гаразд, так що я не думаю, що ви насправді хочете зберегти провідні нулі. Я думаю, що ви хочете відобразити послідовну кількість цифр у виводі.

Так, наприклад, для відображення фіксованого ідентифікатора розміру з 5 цифрами [зауважте, що ідентифікатор 100000 все одно буде відображатися в 6 цифр - все це тут, переконайтеся, що він завжди має щонайменше 5 цифр, і заповніть його "0", якщо номер не достатньо великий], ми могли б зробити це:

std::cout << std::setw(5) << std::setfill('0') << id << ... 

Як альтернатива, як це пропонується в інших відповідях, ви не хочете використовувати ідентифікатор у формі, яка є цілим числом, ви можете просто зберегти її як рядок - якщо ви не збираєтеся робити математику, все, що він змінює це це займає трохи більше пам'яті за книгу.

3
додано
Просто незначна нітпіка, яка ні в якому разі не визначає відповідь. Можливо, ви хочете бути послідовними в застосуванні std :: - або зняти cout або додати його до set * .
додано Автор paxdiablo, джерело

Таких речей, як «провідні нулі» у кількості, немає. "Провідні нулі" - це властивість певної нотифікації, як десяткове представлення числа ASCII. Після перетворення цієї позначки в концептуально абстрактне чисельне представлення, така метрична як "кількість провідних нулів" більше не застосовна (принаймні у десятковій кількості). Вона втрачається без сліду.

Число - це число. Вона не має ніяких "нулів", які ведуть або інакше.

Єдине, що ви можете зробити, це запам'ятовувати, скільки провідних нулів ви мали в оригінальній нотації (або, наскільки широке поле було), а потім, коли ви перетворите число назад у десяткове представлення ASCII, повторно створіть відповідний номер провідних нулів, що використовують цю збережену інформацію.

До речі, у вашому випадку, коли номер вводу представляє ідентифікатор книги з деяким попередньо визначеним форматуванням (наприклад, провідні нулі), ви можете розглянути інший підхід: не перетворюйте ідентифікатор вашої книги в int . Тримайте його як рядок. Це не схоже на те, що вам доведеться виконувати арифметичні операції з ідентифікаторами книжок, чи не так? Швидше за все, вам буде потрібно реляційні та порівняльні порівняння, які можна виконувати на рядках.

2
додано

A = strlen(string) returns the number of characters in your string (say number of digits comprehensive of leading zeros)

B = log10(atoi(string)) + 1 returns the number of digits in your number

A - B => number of leading zeros.

Тепер ви можете відформатувати їх, як вам більше подобається.

2
додано

Я зіткнувся з цим типом проблеми минулого місяця!

Я думаю, що ви можете використовувати метод Format (), що надається класом CString: CString :: Format() форматів і зберігає ряд символів і значень в CString. Кожен необов'язковий аргумент (якщо він є) перетворюється та виводить відповідно до відповідної специфікації формату в pszFormat або з рядок ресурсу, ідентифікованого nFormatID. Наприклад:

CString m_NodeName;
m_NodeName.Format(_T("%.4d"),Recv[2]*100+Recv[3]);
// %.4d means the argument will be formatted as an integer, 
// 4 digits wide, with unused digits filled with leading zeroes

For the detail you can find here: http://msdn.microsoft.com/zh-cn/library/18he3sk6(v=vs.100).aspx

1
додано

Якщо вам потрібні провідні нулі, то int не є правильним типом даних для використання. У вашому випадку вам може бути краще просто зберегти оригінальний рядок.

0
додано

Існує неможливо зберегти int з провідними 0s.

Замість того, що ви хочете зробити, це зробити class для вас:

 class intWithLeadingZeros {
       int number;
       int numberOfLeadingZeros;

       intWithLeadingZeros( string val )
       {
         //trivial code to break down string into zeros and number
       }

       string toString() {
           //trivial code that concatenates leading 0s and number
       }



 };
0
додано
IT KPI C/С++ новым годом
IT KPI C/С++ новым годом
747 учасників

Чат обсуждения С/С++. - Вопросы "напишите за меня лабу" - это оффтоп. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/1147