0

わかりました。これで、学生番号とそれに対応する名前が入力されたテキスト ファイルができました。これらすべてのデータを取得し、適切にフォーマットして(大文字、適切な数のスペースなど)、別のファイルに入れたいと思います。元のテキスト形式は次のようになります。

20111101613 XXXXXXXX  , XXXX
20111121235 xxXXXX, xxxxxx
20111134234   XXXX, XxxX
20111104142 XXXXXxxxX, XXXX
20111131231 XX , XXXXXX

例: 入力ファイルの内容は次のようなものです。

20111112346 Zoomba, Samthing
20111122953 Acosta, Arbyn
20110111241 Smith, John
20111412445 Over, Flow Stack
20111112345 foo, BAR

出力ファイルの内容は次のようになります。

20111122953 ACOSTA, ARBYN
20111112345 FOO, BAR
20111412445 OVER, FLOW STACK
20110111241 SMITH, JOHN
20111112346 ZOOMBA, SAMTHING

編集:正規表現を使用してこの関数を作成する方法について、誰かがヒントや解決策を教えてくれますか?

function sortslist($infile, $outfile)
{
    // open the input file named conversion.txt
    $inptr = fopen($infile, "r");
    if (!$inptr)
    {
        trigger_error("File cannot be opened: $infile", E_USER_ERROR);
    }

    // initialize student number to zero
    $snum = 0;

    // number of letters in the name string
    $n = 0;

    // initialize the name string to be empty
    $name = "";

    // iteratively scan the input file
    $done = false;
    while (!$done)
    {
        // get each character in the file
        $c = fgetc($inptr);

        // if the character is a digit, add it to the student number
        if (ctype_digit($c))
        {
            $snum = (($snum * 10) + ($c - '0'));
        }

        // else, add to name string including commas and space. Input file might have tabs
        else if (ctype_alpha($c) || ($n > 0 && ($c == " " || $c == "\t")) || $c == ",")
        {
            // append the new character to name string
            $name .= $c;

            // add a space after the comma
            if ($c == ",")
            {
                $name .= " ";
                $n++;
            }

            // increment the number of letters
            $n++;
        }

        // end of the line
        else if ($c == "\n" || !$c)
        {
            // 0 is added to student numbers when newline is detected so neglect them
            if ($snum != 0 && $name != "\n")
            {
                // replace consecutive spaces with one space only
                $name = preg_replace(['/\s\s+/', '/\s,/', '/(\s*)(?>$)/'], [' ', ',', ''], $name);

                // record student number and name
                $info['snum'][] = $snum;
                $info['name'][] = strtoupper($name);
            }

            // reset the values needed
            $snum = 0;
            $n = 0;
            $name = "";

            // if we hit the end of the file then it is done
            if (!$c)
            {
                $done = true;
            }
        }
    }

    // sort the students names alphabetically
    array_multisort($info['name'], $info['snum']);

    // combine the name strings and there corresponding student number
    $i = 0;
    $students = [];
    $last_student = end($info['snum']);
    foreach ($info['snum'] as $snum)
    {
        $students[$snum] = $snum . " " . $info['name'][$i++];

        // update input file too
        fwrite($inptr, $students[$snum]);

        // don't add a newline to the end of the file
        if ($snum != $last_student)
        {
            $students[$snum] .= "\n";
        }
    }

    // put it into a new file called slist.txt
    file_put_contents($outfile, $students, LOCK_EX);

    // close the input file
    fclose($inptr);
}
4

1 に答える 1

0

あなたの問題は、$hashtable値が文字列の最初に学生 ID で保存されるという事実にあります。asort()常に値の先頭を見て、それに従ってソートします。したがって、名前で並べ替えるには、学生 ID と名前を 2 つの別々の配列に分割し、 を使用して並べ替える必要がありますarray_multisort()

交換:

$hashtable[$snum] = $snum . " " . strtoupper($name) . "\n";

と:

$snums[] = $snum;
$names[] = strtoupper($name);

array_multisort($names, $snums);

$j = 0;
while ($names) {
    $hashtable[$snum] = $snums[$j]. " ". $names[$j]. "\n";
    $j++;
}
于 2013-04-14T16:17:12.260 に答える