2017-02-22 27 views
-1

В настоящее время я пытаюсь напечатать таблицу пользователей с идентификатором, именем пользователя и паролем. Я достиг сделать доску глядя, как это:Бесконечная петля во время печати таблицы

ID|Username|Password 
--+--------+----------- 
1 |jtar |123456 
2 |mordecai|11111111111 

Как вы можете видеть, я хочу, чтобы иметь возможность масштабировать ячейки таблицы до максимального размера содержимого каждого столбца. Дело в том, что я почему-то получаю бесконечный цикл печатных пространств. Я определил местоположение цикла в моем коде ниже. Я также добавил комментарии для дальнейшего уточнения.

Как показано, я подсчитываю, сколько мест должно быть добавлено после печати каждой из данных пользователя. Если размер строки данных меньше, чем соответствующий тег столбца матрицы (т. Е. Если размер имени пользователя меньше размера строки «Username»), напечатайте разницу в размерах пробелов. Если теперь размер данных больше размера соответствующего тега, распечатайте разницу максимальных данных от каждого размера столбца и размера данных текущего пользователя.

Я добавил операцию или операцию в каждый цикл цикла, чтобы избежать создания инструкции if-else и двух для циклов.

#include <iostream> 
#include <vector> 
#include <sstream> 
#include <string> 
using namespace std; 

class User { 
    int id; 
    string username; 
    string password; 
    public: 
    //Constructor-Destructor 
    User(const int _id, const string _username, const string _password) : id(_id), 
    username(_username), password(_password) { } 
    ~User(){} 

    //Accessors- Mutators 
    int getId() {return id;} 
    string getUsername() {return username;} 
    string getPassword() {return password;} 
}; 

const string intToStr(const int target) 
{ 
    stringstream stream; 
    stream << target; 
    return stream.str(); 
} 

int main() { 
    vector<User*> userList; 
    int maxIdLength = 0, maxUsernameLength = 0, maxPasswordLength = 0; 
    //create users 
    for(int i = 0; i < 20; i++) { 
     userList.push_back(new User(i, "user" + i, "genericpass")); 
    } 

    //find maximum lengths 
    for (vector<User*>::iterator it = userList.begin(); (it != userList.end()); it++) { 

     if (maxIdLength < intToStr((*it)->getId()).size()) 
      maxIdLength = intToStr((*it)->getId()).size(); 

     if (maxUsernameLength < (*it)->getUsername().size()) 
      maxUsernameLength = (*it)->getUsername().size(); 

     if (maxPasswordLength < (*it)->getPassword().size()) 
      maxPasswordLength = (*it)->getPassword().size(); 
    } 

    //print headlines 
    cout << "ID"; 
    for (int i = 0; i < maxIdLength - 2; i++) 
     cout << " "; 
    cout << "|Username"; 
    for (int i = 0; i < maxUsernameLength - 8; i++) 
     cout << " "; 
    cout << "|Password"; 
    for (int i = 0; i < maxPasswordLength - 8; i++) 
     cout << " "; 
    cout<<endl; 

    //print cosmetic line 
    cout << "--"; 
    for (int i = 0; i < maxIdLength - 2; i++) 
     cout << "-"; 
    cout << "+--------"; 
    for (int i = 0; i < maxUsernameLength - 8; i++) 
     cout << "-"; 
    cout << "+--------"; 
    for (int i = 0; i < maxPasswordLength - 8; i++) 
     cout << "-"; 
    cout << endl; 

    for (vector<User*>::iterator it = userList.begin(); (it != userList.end()); it++) {//start printing the users 
    //Infinite Loop bug in the second conditional argument of the for loops 
      cout << (*it)->getId();//id 

      for (int i = 0; (i < maxIdLength - intToStr((*it)->getId()).size()) || (i < (2 - intToStr((*it)->getId()).size())); i++) 
       cout << " "; 
      cout << "|" << (*it)->getUsername();//username 

      for (int i = 0; (i < (maxUsernameLength - ((*it)->getUsername()).size())) || (i < (8 - ((*it)->getUsername()).size())); i++) 
       cout << " "; 
      cout << "|" << (*it)->getPassword();//password 
      for (int i = 0; i < maxPasswordLength - (*it)->getPassword().size() || i < 8 - (*it)->getPassword().size(); i++) 
       cout << " "; 
     cout<<endl; 
    } 

    while(!userList.empty()) { 
     delete userList.back(); 
     userList.pop_back(); 
    } 
    return 0; 
} 
+1

Где у вас есть «бесконечное «петля? Не могли бы вы указать на код, который вы показываете? Или еще лучше, попытайтесь удалить все несвязанные коды, чтобы создать [Минимальный, Полный и Подтверждаемый Пример] (http://stackoverflow.com/help/mcve). –

+2

Кроме того, пытались ли вы использовать отладчик для выполнения кода, по очереди, чтобы увидеть, что он делает, чего вы не ожидали от него? –

+0

Я указал, что бесконечный цикл создается в hte втором условном аргументе петель ниже. Кроме того, это минимальная версия, фактический код намного больше. Это минимальный, полный и проверяемый пример –

ответ

4

Обычно компилятор должен жаловаться, потому что вы сравниваете int с size_t, который без знака, так 2 - xxx.size() беззнаковая и если размера больше, чем 2, он становится большим числом.

example см

Возможное решение static_cast размера, чтобы Int.

+0

'Обычно компилятор должен жаловаться', и он делает это, если вы не подавляете предупреждения вручную. – SingerOfTheFall

+0

Я использую VS, поэтому он не жаловался. –

+0

проверьте [здесь] (https://msdn.microsoft.com/en-us/library/y92ktdf2.aspx), если вы хотите, чтобы вас предупреждали, вместо того, чтобы искать странную логику. – stefaanv

1

Одна из проблем, я могу обнаружить, что вы добавляете int i к RValue string user:

for(int i = 0; i < 20; i++) { 
    userList.push_back(new User(i, "user" + i, "genericpass")); 
} 

вы должны использовать itoa, насыпать I в значение string