1

誰かがこれを間に合うように見るかどうかはわかりませんが、やってみます... 私は C++ の入門クラス (学部生) にいて、月曜日の朝に期限が来る課題があります...(はい!先延ばし:)、)

Ok。この形式で生徒の記録を読み取る必要があります。

Adriana,Smith,692493955,50,43,52,86,74,83
Adrienne,Johnson,480562092,75,72,93,71,81,89
Bla, Bla, Bla

ファイル (最大 200) から並べ替えなどを行います。

他の必要な機能はすべて作成できましたが、確認できません。

ファイルを開き、各行を読み取り、各行内で各トークンを読み取り、それらを一時配列に格納する関数を作成しました。この tempArr[9] は、実際の配列 [9][200] に配置される前に検証されます。

ファイルを開き、最初の行を読み取って配列にトークン化することができましたが、while ループが繰り返されると、ファイルの最初の行が再び読み取られるため、実際の配列を出力すると +/ が返されます。 -200回の最初の記録。

私は自分のマニュアル、cplusplus.com の getline() 情報を何度も読み直し、フォーラムで検索し、約 100 万回コードを切り替えました。

助けて!

fn は次のとおりです。

void getFile(std::string realArray[][200], const int ROW_SIZE)
{
    std::string filename, token, line;

    int positionLine(0);
    int positionToken(0);
    int row(0);
    int numOfLine(0);
    const int ROWS (9);
    const int MAX_RECORDS (200);
    std::string tempArray[ROWS];

    std::cout << "Please enter the desired filename with it's extension:\t ";
    std::cin  >> filename;

    const char *file=filename.c_str();
    std::ifstream input(file, std::ios::in);

    while (!input.is_open())
    {
        std::cout <<    "The file did not open correctly. \n\nPlease enter a valid filename.\n";
        std::cin  >> filename;

        const char *file=filename.c_str();
        std::ifstream input(file, std::ios::in);
    }

    while (input.good() && numOfLine < MAX_RECORDS)
    {
        getline (input,line);
        std::istringstream inputss (line);

        while (getline(inputss, token, ',') && row < ROWS )
        {
            tempArray[row] = token; 

            row++;
        }
        numOfLine++;

        validateData (tempArray,ROWS , numOfLine);

        storeData(tempArray, ROWS, realArray, ROW_SIZE, numOfLine);

    }

    if (numOfLine == MAX_RECORDS)
    {
    std::cout << "The maximum number of records to be read (" << MAX_RECORDS << ") has been reached.\n";
    }

}   

PS私はVisual Studio 2010に取り組んでおり、私のファイルは* .dosです

ああ、私は取り出した

名前空間 std を使用します。

それが与えていたので: cout is ambiguous error.

ありがとうございます。

4

2 に答える 2

3

どこから始めれば!!!!

悪い習慣。1行に1つ!

std::string filename, token, line;

これらは未使用です。それらを削除します。

int positionLine(0);
int positionToken(0);

文字列へのポインターを新しい変数に抽出しないでください。
ファイル名が変更された場合、ファイルは無効になります。
結果が関数に渡される場合にのみ安全に使用できます。

const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);

したがって、このようにする必要があります。

std::ifstream input(file.c_str());

ここ。完全に新しい variable を宣言していますinput。この変数は他の変数とは何の関係もありませんinput。このバージョンは、while ループの最後で範囲外になると破棄されます。

while (!input.is_open())
{
    // <STUFF DELETED>
    std::ifstream input(file, std::ios::in);
}

これは非常によくある間違いです。
ここで良好な状態をテストすることは (通常) 間違っています。これは、通常、ファイルの終わりに達したときにループを終了させたいためです。しかし、最後の読み取りは実際にはファイルの最後まで読み取りますが、ファイルの終わりを超えないため、EOF フラグをトリガーせず、ループに再び入ります。その後、次の読み取りは失敗します。

while (input.good() && numOfLine < MAX_RECORDS)
{
    getline (input,line);

より良いバージョンは次のとおりです。

while (getline (input,line) && numOfLine < MAX_RECORDS)
{

ここで正しいことがわかります:

    while (getline(inputss, token, ',') && row < ROWS )
    {

ここでは、行をインクリメントして にインデックスを付けますtempArray。しかし、その行が 0 にリセットされる場所はわかりません。

        tempArray[row] = token; 
        row++;

編集:

以下のBoのコメントに基づいています。

技術的には、次のことを行っても問題はありません。

const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);

ここでは、fileはすぐに使用され、二度と使用されません。経験から、これを行うことで、他の人が自由に再利用できるコンテキストに新しい変数を導入したことがわかりました。通常、これは問題にはなりませんが、この特定のポインターは目に見えないほど無効になる可能性があります (ファイル名オブジェクトが変更されると、ファイル ポインターが無効になる可能性があります)。

これはメンテナンスの問題であり、複数の開発者がコードを変更している場合は特に危険です。file後で開発者「A」と開発者「B」が変数をコードで再利用すると、変数を変更するコードが追加さfilenameれ、危険な状況に陥ります。

したがって、目に見えないほど無効になる可能性のあるポインターを格納しない方が常に安全です。したがって、これらを安全に使用する唯一の方法は、関数のパラメーターとして使用することです。

std::ifstream input(filename.c_str(), std::ios::in);

私が最近遭遇した別の状況は、わずかに異なるコンテキストでの同じ問題でした:

QString   path(<Some String>);
char*     file = path.toLatin1().data();
readFile(file);

ここでの問題は、toLatin() が QByteArray のオブジェクトを返すことです。このオブジェクトは値によって返され、どの変数にも割り当てられないため、一時的なものです。一時オブジェクトは式の最後で破棄されるため、QByteArray の内部部分へのポインタを返したメソッド data() は変数fileに無効な値を代入しました。打たれます。

これを行う安全な方法は、結果をパラメーターとして関数に直接渡すことでした。

readFile(path.toLatin1().data());
于 2011-04-03T06:56:59.233 に答える
1

私の推測では、... の値を再設定していないrowので、行をインクリメントして の値を超えると、ROWS内に新しい値を格納するのをやめますtempArray。したがって、 からファイルを問題なく読み取っていますgetline()が、それらの新しい値を tempArray に保存して一度検証することはしていませんrow >= ROWS

の値をリセットするとrowうまくいくはずです。また、関数がどのように動作するかによっては、前のループから保存されたデータが現在のループで読み取られたデータと混ざらないようにvalidateData()、 の値を渡すこともできます。あなたはデータの量を読みました。rowROWSgetline(inputss, token, ',')ROWS

お役に立てれば、

ジェイソン

于 2011-04-03T03:50:50.973 に答える