【问题标题】:Separating parallel arrays from txt file从 txt 文件中分离并行数组
【发布时间】:2015-04-19 23:15:20
【问题描述】:

我是一个非常新手的程序员,我正在尝试制作一个程序来读取一个包含 5 个学生姓名(仅限名字)的 txt 文件以及每个学生的四个考试成绩。我正在尝试将名称读入一个名为 students 的数组中,然后将分数读入 4 个名为 test1、test2、test3、test4 的单独数组中,然后从监视器上显示它。该文件如下所示:

史蒂夫 78 65 82 73

肖恩 87 90 79 82

安妮 92 90 89 96

卡罗尔 72 65 65 60

凯西 34 50 45 20

我很难分解阵列并组织它们。有人能帮我吗?请记住我是新手,所以我对编程知之甚少。

这是我目前的代码:

#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <ctime>
#define over2 "\t\t"
#define over3 "\t\t\t"
#define over4 "\t\t\t\t"
#define down5 "\n\n\n\n\n"


using namespace std;



int main(int argc, char *argv[])
{

    
    ifstream inputFile;
    
    
    //Constant for max string size
    const int SIZE = 5;
     

    //Constant for the scores
    string names[SIZE], fileName, line, test1[SIZE], test2[SIZE], test3[SIZE], test4[SIZE];


    //input section, user enters their file name
    cout << down5 << down5 << over2 << "Please enter your file name: ";
    cin >> fileName;
    system("CLS");
    

    

    //open the file containing the responses
    inputFile.open(fileName.c_str());
     cout << endl;

    //kicks you out if file isn't found
    if (inputFile)
    {
        for(int i = 0; i < SIZE; i++)
        {  
           getline(inputFile, line);
            names[i] = line;
            getline(inputFile, line);
            test1[i] = line;
            getline(inputFile, line);
            test2[i] = line;
            getline(inputFile, line);
            test3[i] = line;
            getline(inputFile, line);
            test4[i] = line;
        }   
            inputFile.close();  
    }
    cout << down5 << over3 << "Student\tTest1\tTest2\tTest3\tTest4\n";
    cout << over3 << "-------\t-----\t-----\t-----\t-----\n";   
    for(int i = 0; i < SIZE; i++)
    {
        cout << over3 << names[i] << endl;
        cout << over3 << test1[i] << endl;
        cout << over3 << test2[i] << endl;
        cout << over3 << test3[i] << endl;
        cout << over3 << test4[i] << endl;
        
    }
    return 0;
}

【问题讨论】:

    标签: c++ arrays file-io


    【解决方案1】:

    让我们看看你要读取的文件的结构:

    Steve 78 65 82 73
    Shawn 87 90 79 82
    Annie 92 90 89 96
    Carol 72 65 65 60
    Kathy 34 50 45 20
    

    数据的格式可以描述如下:

    • 每一行代表一个“记录”。
    • 每个“记录”包含多个列。
    • 列由空格分隔。

    您当前为每个使用getline()

    for(int i = 0; i < SIZE; i++)
    {  
      getline(inputFile, line);
      names[i] = line;
      getline(inputFile, line);
      test1[i] = line;
      getline(inputFile, line);
      test2[i] = line;
      getline(inputFile, line);
      test3[i] = line;
      getline(inputFile, line);
      test4[i] = line;
    }   
    

    ...而您实际上想为每个 record 读取一行并将其拆分:

    for (int i = 0; i < SIZE; i++)
    {
      string line;
      size_t start = 0;
      // For each line, attempt to read 5 columns:
      getline(inputFile, line);
      names[i] = get_column(line, start);
      test1[i] = get_column(line, start);
      test2[i] = get_column(line, start);
      test3[i] = get_column(line, start);
      test4[i] = get_column(line, start);
    }
    

    这是您的原始代码的修改版本,它按上述方式拆分每一行:

    #include <cctype>
    #include <fstream>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    static string get_column(string line, size_t &pos)
    {
      size_t len = 0;
      // Skip any leading whitespace characters.
      while (isspace(line.c_str()[pos])) { ++pos; }
      // Count the number of non-whitespace characters that follow.
      while (!isspace(line.c_str()[pos+len]) && line.c_str()[pos+len]) { ++len; }
      // Extract those characters as a new string.
      string result = line.substr(pos, len);
      // Update the "start" position (for the next time this function is called).
      pos += len;
      // Return the string.
      return result;
    }
    
    int main()
    {
    
      const int SIZE = 5;
      string names[SIZE], test1[SIZE], test2[SIZE], test3[SIZE], test4[SIZE];
    
      // Ask the user to enter a file name.
      cout << "Please enter your file name: ";
      string fileName;
      cin >> fileName;
    
      // Open the file and read the data.
      ifstream inputFile(fileName.c_str());
      if (!inputFile.is_open()) { return 0; }
    
      for (int i = 0; i < SIZE; i++)
      {
        string line;
        size_t start = 0;
        // For each line, attempt to read 5 columns:
        getline(inputFile, line);
        names[i] = get_column(line, start);
        test1[i] = get_column(line, start);
        test2[i] = get_column(line, start);
        test3[i] = get_column(line, start);
        test4[i] = get_column(line, start);
      }
    
      inputFile.close();
    
      // Display the data.
      cout << "Student\tTest1\tTest2\tTest3\tTest4" << endl;
      cout << "-------\t-----\t-----\t-----\t-----" << endl;
    
      for(int i = 0; i < SIZE; i++)
      {
        cout << names[i] << "\t";
        cout << test1[i] << "\t";
        cout << test2[i] << "\t";
        cout << test3[i] << "\t";
        cout << test4[i] << endl;
      }
    
    }
    

    运行程序会产生以下输出:

    Please enter your file name: textfile.txt
    Student Test1 Test2 Test3 Test4
    ------- ----- ----- ----- -----
    Steve   78    65    82    73
    Shawn   87    90    79    82
    Annie   92    90    89    96
    Carol   72    65    65    60
    Kathy   34    50    45    20
    

    注意get_column() 函数处理多个空格或太短的行,所以这个文件:

    Steve 78     65 82 73
    Shawn   87 90 
    Annie 92 90 89 96
    Carol 72 
    Kathy 34 50   45 20
    

    ...产生以下输出:

    Please enter your file name: textfile.txt
    Student Test1 Test2 Test3 Test4
    ------- ----- ----- ----- -----
    Steve   78    65    82    73
    Shawn   87    90
    Annie   92    90    89    96
    Carol   72
    Kathy   34    50    45    20
    

    【讨论】:

    • 当我运行这个函数时,它只是输出随机数......为什么会这样?另外,我非常非常新手,你的 get_column 函数对我来说绝对没有意义。 ://
    • get_column() 函数接受一个字符串和一个“起点”,然后从它找到的第一组(非空白)字符创建一个 new 字符串“初始点。如果您看到奇怪的结果,请确保在第一次调用之前将“开始”位置设置为0;之后,开始位置由pos += len 行更新。要了解如何它的工作原理,请阅读isspace() 函数和substr() 方法。
    • 另外,如果我想计算每个分数的平均值并显示出来,最简单的方法是什么?
    • 使用atof()strtod() 将字符串转换为数字:double average = (atof(test1[i]) + atof(test2[i]) + atof(test3[i]) + atof(test4[i])) / 4; 注意这里使用double 而不是int - 在某些情况下整数除法会导致奇怪的结果.例如,比较3/2(整数)与3.0/2.0(浮点)的结果。
    • 我会在哪里将它插入到我的代码中?我该如何申报?
    【解决方案2】:

    前面的答案是想太多了。

    您可以使用您的输入文件流来检索“格式化输入”(即,您知道输入格式为“字符串”,然后是“int”、“int”、“int”、“int”)使用 >> 运算符。

    string name;
    
    int score[4];
    
    ifstream mf;
    
    mf.open("score.txt");
    
    // Get name string.
    mf >> name;
    
    // Get four score values into an array.
    mf >> score[0] >> score[1] >> score[2] >> score[3];
    

    然后:

    cout << name;
    
    cout << score[0];
    cout << score[1];
    cout << score[2];
    cout << score[3];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多