逐行读取文件,然后写入C 中的数组

Read a file line by line and write to an array in C++

本文关键字:数组 读取 文件 然后 逐行      更新时间:2023-10-16

我是C 的新手,我在lynda.com教练提供的练习时遇到了麻烦。

我应该创建一个带有单词行的txt文件。我们使用线路ifstream读取它,然后将字符串存储到字符串数组中。(注意:此任务还有其他与我的问题无关的部分。)

所以,我有三个问题:

  1. 当我运行讲师提供的解决方案时,尽管它进行了编译和运行,但它具有exc_bad_access。

    这是她的代码:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cstring>
    #include <fstream>
    using namespace std;
    string getRandomReply(string [], int);
    int main()
    {
        ifstream inputfile;
        // Declare an input file
        inputfile.open("replies.txt", ios::in);
        char answer[30];
        string answers[20];
        int pos = 0;
        // Read from the file until end of file (eof)
        while (!inputfile.eof())
        {
            inputfile.getline(answer, 30);
            answers[pos] = answer;
            pos++;
        }
        cout << "Think of a question for the fortune teller, "
        "npress enter for the answer " << endl;
        cin.ignore();
        cout << getRandomReply(answers, 20) << endl;
        return 0;
    }
    string getRandomReply(string replies[], int size)
    {
        srand(time(0));
        int randomNum = rand()%20;
        return replies[randomNum];
    }
    
  2. 即使此程序功能正常,我也不明白需要创建char []并将值分配到字符串数组中。

  3. 在进行练习时,我已经编写了自己的代码版本,该练习是编译和运行但用白色空间返回的。

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cstring>
    #include <fstream>
    int main(int argc, const char * argv[]) {
        std::ifstream inputfile;
        inputfile.open("replies.txt", std::ios::in);
        std::string answers[20];
        int pos = 0;
        // Read from the file until end of file (eof)
        while (inputfile.good())
        {
            getline(inputfile, answers[pos], 'n');
            pos++;
        }
        for (int i=0; i<20; i++)
        {
            std::cout << answers[i] << std::endl;
        }
        /*
            srand(time(0));
            std::cout << "Think of a question that you would like to ask fortune teller." << std::endl;
            int ranNum = rand()%20;
            std::string answer = answers[ranNum];
            std::cout << answer << std::endl;
         */
        return 0;
    }
    

eesh,我不认为我会继续进行此特定课程。

在您老师的代码中,我猜(但不能确定,因为您没有给出输入),您的答案索引数组(pos)在数组的末端流出并给您老师代码中的exec_bad_access。

http://www.cplusplus.com/reference/istream/istream/estream/getline/

如果函数提取不提取字符,或者如果 一旦(n-1)字符没有发现划界字符 已经写给S。请注意,如果以下角色 输入序列中的那些(n-1)字符恰恰是 划界字符,也被提取,而失败标志不是 集(提取的序列正好是n个字符)。

inputfile.getline(答案,30)以此形式设置ifstream上的故障,如果任何问题都超过30个字符,因为它尚未到达定界线(默认为newline)。

不更改任何数据结构(在C 中有更好的数据结构),如果添加类似的内容,则可能有效:

// Read from the file until end of file (eof)
while (!inputfile.eof())
{
  inputfile.getline(answer, 30);
  answers[pos++] = answer;
  while (!inputfile)
  {
    inputfile.clear();
    inputfile.getline(answer, 30);
  }
}

这将在每次呼叫getline之后清除失败的问题,并尝试完成30多个字符(如果有30多个字符)。问题是,如果设置了故障,则循环将永远运行,因为!ifstream.eof(),而条件永远无法满足。这意味着您的pos索引将永远递增并从数组的末端流出。

,文件中可能还有比固定大小数组可以存储的问题更多的问题。

使用调试器的评论并不是很不错的。这就是您解决这些问题的方式。您需要在Xcode调试器上的一些初学者阅读材料(也许是?)。对于几乎任何初学者操作(检查变量的值,设置断点等),它都可以通过GUI完成,应该很简单。

关于您的代码(最好不要在堆栈上混合两个问题),它在添加包含std :: String和getline Overload的include <string>之后对我来说很好。但是,我没有与您相同的输入。在调用getline的循环中设置一个断点。如果您的路径错误或阅读输入的某些问题,您甚至都不会输入该循环,并且您将通过一堆空字符串迭代并将其打印出来。