簡體   English   中英

如何將一個while循環與for循環結合?

[英]How Can i combine one while loop with a for loop?

我正在按照說明將這兩個循環組合在一起,但是我無法弄清楚應該如何做這樣的事情。 因為我的計數器我在for循環中不能進入while循環條件。 我的老師希望程序僅執行一個循環。 提前致謝。 該代碼基本上遍歷txt文件,應該首先將值分配給數組,然后在for循環中將其分配給指針。

我這部分有問題:

void fillArr(vector <student> &arr, vector <student *> &ptrels){
    student temp;

    ifstream inFile ("index.txt");
    while (!inFile.eof()) {
        inFile >> temp.fName >> temp.Lname >> temp.gpa >> temp.id >> temp.email;
        arr.push_back(temp);
    }
    for (unsigned i = 0; i < arr.size(); i++ ){
        ptrels.push_back(&arr[i]);
    }

//    combine the two above loops
}

這是完整的代碼:

> #include <string>
> #include <cstdio>
> #include <iostream>
> #include <vector>
> #include <fstream>
> #include <sstream> using namespace std;
> 
> struct student {
>     string fName, Lname, email, id;
>     double gpa; } ;
> 
> void input(); void fillArr(vector <student> &arr, vector <student *>
> &ptrels); void printFile(vector <student *> pointarray); void
> sortFile(vector <student> &arr, vector <student *> &pointarray);
> 
> int main() {
>     vector <student> elements;
>     vector <student *> ptrels;
>     
>     ifstream inFile;
>     inFile.open("index.txt");
>     
>     int answer;
>     fillArr(elements, ptrels);
>     cout << "Please select:" << endl
>     << "1 = Select All" << endl
>     << "2 = Order A-Z by Name"<<endl
>     << "3 = To exit"<< endl;
>     cin >> answer ;
>     if (answer == 1){
>         printFile(ptrels);
>         main();
>     }
>     if (answer ==2){
>         sortFile(elements, ptrels);
>         printFile(ptrels);
>         main();
>     }
>     if (answer ==3){
>         inFile.close();
>         exit(0);
>     }
>     else {
>         cout << "Invalid Try Again:"<< endl;
>         main();
>     }
>     return 0; }
> 
> void fillArr(vector <student> &arr, vector <student *> &ptrels){
>     student temp;
> 
>     ifstream inFile ("index.txt");
>     while (!inFile.eof()) {
>         inFile >> temp.fName >> temp.Lname >> temp.gpa >> temp.id >> temp.email;
>         arr.push_back(temp);
>     }
>     for (unsigned i = 0; i < arr.size(); i++ ){
>         ptrels.push_back(&arr[i]);
>     }
> 
> //    combine the two above loops }
> 
> 
> 
> void printFile(vector <student *> pointarray){
>     for (unsigned j = 0; j < pointarray.size(); j++){
>         cout << pointarray[j] -> fName << "    ";
>         cout << pointarray[j] -> Lname<< "    ";
>         cout << pointarray[j] -> gpa << "    ";
>         cout << pointarray[j] -> id << "    ";
>         cout << pointarray[j] -> email << "    ";
>         cout << endl;
>     } }
> 
> //swap the elements by pointer. you are swaping the record not the
> pointers. // only sorting by firstname, sort by all 5 void
> sortFile(vector <student> &arr, vector <student *> &pointarray){
>     for(unsigned i = 0; i < arr.size(); ++i){
>         for(unsigned j = i + 1; j < arr.size(); ++j) {
>             if(arr[i].fName > pointarray[j] -> fName) {
>                 swap(arr[i].fName,pointarray[j] ->fName);
>                 swap(arr[i].Lname,pointarray[j] ->Lname);
>                 swap(arr[i].gpa,pointarray[j] ->gpa);
>                 swap(arr[i].id,pointarray[j] ->id);
>                 swap(arr[i].email,pointarray[j] ->email);
>             }
>         }
>     } }

我也知道我應該在一個不同的問題中問這個問題,但是她也希望我進行排序,這是最后一個對sortFile進行排序的函數,它不僅對firstName進行所有值的排序。 再加上她討厭交換功能,尋找替代方案。 任何提示將不勝感激。

一個幼稚的解決方案可能會將兩個循環分解為以下內容:

void fillArr(vector <student> &arr, vector <student *> &ptrels){
    student temp;

    ifstream inFile ("index.txt");
    while (!inFile.eof()) {
        inFile >> temp.fName >> temp.Lname >> temp.gpa >> temp.id >> temp.email;
        arr.push_back(temp);
        ptrels.push_back(&arr.back());
    }
//    combine the two above loops
}

假定arr.empty()是此函數的前提(如果不是,則語義會被破壞),這幾乎可以做同樣的事情。

幾乎。

麻煩的是,每個arr.push_back(temp)可能會導致arr的擴展,從而使到目前為止放置在ptrels所有指針失效。 原始解決方案使用了第二個循環,這樣您就可以在開始弄亂指針之前知道arr已完成並且已塵土飛揚。

只要我們通過在向量中reserve空間來防止重新分配,我們仍然可以使用單循環解決方案。 為此,您需要預先知道需要多少個元素。 為此,您將需要使用兩次"index.txt" ,然后返回到兩個循環。

因此,基本上,不,您不能這樣做。

真正的解決方案是拒絕該要求。 希望這就是您的老師要您報告的內容。 無論如何,在這樣的簡單情況下,我無法想到“索引”向量的任何實際用例。

另外,請注意您的I / O方法

這樣,您就可以發布整個代碼了; 解決方案是完全消除對指針向量的需要。

通過嘗試按您的方式處理兩個向量,會使排序函數的工作變得更加困難。 並且您的printFile()與使用指針相比,使用指針要簡單得多。

我不明白為什么首先要有這個指針向量。 除了有時它們用來嘗試對組執行排序,而無需更改原始組的順序。 由於您確實更改了訂單,因此這是痛苦的向量。

擺脫它; 讓生活變得簡單。

另外:您的sortFile()可以使用std :: sort,不僅變得更快,而且更易於閱讀。

C ++ 17代碼(我將sort函數主體留空了,以便為作業做一些事情,而且我認為那部分應該是Main Thing™):

// Source encoding: utf-8 with BOM ∩
#include <string>               // std::(string)
#include <iostream>             // std::(cout, cerr)
#include <optional>             // std::(optional)
#include <utility>              // std::(move)
#include <vector>               // std::(vector)
#include <fstream>              // std::(ifstream)
#include <sstream>              // std::(istringstream)
#include <stdexcept>            // std::(exception, runtime_error)
using namespace std;

auto hopefully( bool const e ) -> bool { return e; }
[[noreturn]] auto fail( string const& s ) -> bool { throw runtime_error( s ); }

auto optional_line_from( istream& stream )
    -> optional<string>
{
    string result;
    return getline( stream, result )? result : optional<string>{};
}

struct Student_info
{
    string first_name;
    string last_name;
    double gpa;
    string id;
    string email;
};

// Originally
// void fillArr(vector <Student_info> &arr, vector <Student_info *> &ptrels):

auto data_from( string const& filename )
    -> vector<Student_info>
{
    ifstream in_file{ "index.txt" };
    hopefully( not in_file.fail() )
        or fail( "Failed to open “index.txt” for reading." );

    vector<Student_info> result;
    while( optional<string> line = optional_line_from( in_file ) )
    {
        Student_info temp;
        istringstream items{ *line };
        items >> temp.first_name >> temp.last_name >> temp.gpa >> temp.id >> temp.email;
        hopefully( not items.fail() )
            or fail( "Failed to parse input line: “" + *line + "”." );
        result.push_back( move( temp) );
    }
    return result;
}

auto operator<<( ostream& stream, Student_info const& item )
    -> ostream&
{
    stream
        << item.first_name << "    "
        << item.last_name<< "    "
        << item.gpa << "    "
        << item.id << "    "
        << item.email;
    return stream;
}

// Originally
// void printFile(vector <student *> pointarray):

void print( vector<Student_info const*> const& pointers )
{
    for( auto const p : pointers ) { cout << *p << endl; }
}

// Originally
// void sortFile(vector <student> &arr, vector <student *> &pointarray):

void sort( vector<Student_info const*>& pointarray )
{
    // TODO:
    // Using std::sort is a good idea, if you're allowed to do that.
    // std::tuple instances can be lexicographically compared with `<`, and
    // `std::tie` produces a tuple. That's great for the current job.
}

// Originally
// int main():

void cpp_main()
{
    vector<Student_info> const data = data_from( "index.txt" );

    vector<Student_info const*> pointers;
    for( Student_info const& item : data ) { pointers.push_back( &item ); }

    for( ;; )
    {
        cout << "Please select\n"
             << "1 = Select All\n"
             << "2 = Order A-Z by Name\n"
             << "3 = To exit"
             << endl;
        try
        {
            switch( stoi( *optional_line_from( cin ) ) )
            {
                case 1:
                {
                    print( pointers );
                    break;
                }
                case 2:
                {
                    sort( pointers );
                    print( pointers );
                    break;
                }
                case 3:
                {
                    return;
                }
                default:
                {
                    fail( "" );
                }
            }
        }
        catch( ... )
        {
            // Avoid infinite loop on input failure:
            if( cin.fail() )
            {
                fail( "Failed reading standard input." );
            }
            cout << "Invalid Try Again:" << endl;
        }
    }
}

auto main()
    -> int
{
    try
    {
        cpp_main();
        return EXIT_SUCCESS;
    }
    catch( exception const& x ) 
    {
        cerr << "!" << x.what() << endl;
    }
    return EXIT_FAILURE;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM