【问题标题】:Using getline to read from file to a 2d string array使用 getline 从文件读取到二维字符串数组
【发布时间】:2013-02-23 23:29:40
【问题描述】:

我正在尝试将文本文件的内容读入二维字符串数组,但无论我尝试或搜索了什么,我都找不到解决方案。该代码应该加载一个文本文件,通过查找水平选项卡将其分成元素并显示输出。当我按原样运行代码时,我收到一个从网上搜索发现的错误,这意味着我正在尝试操纵我不应该操纵的内存。我不是要求编写代码,只是朝着正确的方向推动。提前谢谢你。

这是我运行程序时得到的:

0x23fd5c

Process returned -1073741819 (0xC0000005)   execution time : 2.344 s
Press any key to continue.

编辑:: 我已经更正了代码,因此它现在可以正常运行,但它没有正确地将每一行的最后一个条目存储在文本文件中。我可以以某种方式显示最后一个条目的数字 100,但是当我尝试传递该位置或仅显示 playList[0][5] 时,它表示它等于下一行的第一个条目。任何帮助都会很棒,我在下面发布了当前代码。

这是我的代码:

 #include <iostream>
 #include <string>
 #include <iomanip>
 #include <cstdlib>

 using namespace std;

 void readTextFile( int &Count, string playList[50][5]);
 void userAddition( int &Count, string playList[50][5]);




int main()
{
string decision;
string playList[50][5];
int Count = 0;
readTextFile(Count, playList);

cout << "If you would like to add to the list, Please enter 'Y'. If you would like to exit     
 please enter 'N'. ---->  ";
getline(cin, decision);
if (decision=="y" || decision=="Y")
    userAddition(Count, playList);
else
{
    return(0);
}

return 0;
} // End of Main FN.






void readTextFile( int &Count, string playList[50][5])
{

string inputfield;

ifstream infile("c:\\cTunes.txt", ifstream::in);
    if ( infile.is_open() )
    {
        // File is read.
    }   // end if
    else
    {
        cout << "Error Opening file" << endl;
        return; //Program Closes.
    }  // end else

    cout << setw(30)<<left<< "TITLE"<< setw(10) <<left<<"LENGTH"<<  
      // Outputs a title to          each column that is displayed.
    setw(40)<< left<<"ARTIST"<< setw(40) << left<<"ALBUM"<<
    setw(15) << left <<"GENRE" << setw(5) << left << "RATING" << endl;

getline(infile, inputfield, '\t');    // read until tab
while(! infile.eof())  // loop until file is no longer valid.
 {

        playList[Count][0] = inputfield;
        getline(infile, inputfield, '\t');           // read until tab.

        playList[Count][1] = inputfield;
        getline(infile, inputfield, '\t');             // read until tab.

        playList[Count][2] = inputfield;
        getline(infile, inputfield, '\t');           // read until tab.

        playList[Count][3] = inputfield;
        getline(infile, inputfield, '\t');          // read until tab.

        playList[Count][4] = inputfield;
        getline(infile, inputfield);                // read until end of line.
        playList[Count][5] = inputfield;

    cout << setw(30)<<left<< playList[Count][0] << setw(10) <<left<<playList[Count][1] <<          
    // Output the line number equal to count.
    setw(40)<< left<<playList[Count][2] << setw(40) << left<< playList[Count][3] <<
    setw(15) << left << playList[Count][4] << setw(5) << left << playList[Count][5] <<                     
    endl;

    /*cout <<"Title: " << setw(25)<<left<< playList[Count][0]<<endl;
    cout <<"Length: " << setw(5) <<left<<playList[Count][1] << endl;
    cout <<"Artist: " << setw(50)<< left<<playList[Count][2] << endl;
    cout <<"Album: " << setw(40) << left<< playList[Count][3] << endl;
    cout <<"Genre: " << setw(15) << left << playList[Count][4] << endl;
    cout <<"Rating: " << setw(5) << left << playList[Count][5] << endl<<endl;*/

    Count++;            // Increment counter by 1
    getline(infile, inputfield, '\t'); // read next line until tab.

    }    // end while
 infile.close(); // close the file being read from.
 cout<<endl<<endl<<playList[0][5]<<endl;
 } // End of readTextFile

我相信 getline 在阅读到行尾时会导致问题,但我真的很茫然。

【问题讨论】:

  • string playList[19][5]; 为什么?!为什么不使用vector &lt;vector &lt;string&gt; &gt;
  • 如果您附加了示例输入 + 预期输出,您将获得更适合您的具体情况的答案。
  • 另请注意,当打开文件时出现错误:else { cout &lt;&lt; "Error Opening file" &lt;&lt; endl; },您可能应该使用return 来防止执行其余函数。
  • 示例输入来自文本文件,其中的术语由水平制表符分隔。有五个术语:Title、Length、Album、Genre、PlayCount。该程序应该读取将每个术语放入数组的文本文件,并在到达行尾时从新行开始。现在我只是试图填充数组并输出它,以确保它被正确填充。
  • 好的,谢谢。我将添加退货。

标签: c++ arrays string file-io text-files


【解决方案1】:

首先,请注意以下行:

cout << playList << endl;

您正在打印数组的地址,而不是内容。你会需要 打印内容的循环。

其次,在以下代码中:

if ( infile.is_open() )
{
   // ok, read in the file
}    // end if
else
{
cout << "Error Opening file" << endl;
//a return statement is missing
}

您需要一个 return 语句来避免从关闭的流中读取(这可能导致崩溃)

最后,你的函数没有返回任何东西,所以它应该被声明为 void 或返回一些值(根据上下文没有意义)。

希望对您有所帮助,祝您好运!

【讨论】:

  • 感谢您的帮助。打印地址会给我上面发布的错误吗?当我运行代码时,windows 提示我关闭程序,而不是编译器,这让我相信我访问了我不应该访问的东西。我将函数切换为 void,并在错误检查中添加了返回。
  • 很难说,因为当我使用 minGW 编译器编译时,即使在修复之前,您的代码对我来说也可以正常工作。你在用视觉工作室吗?
  • 我已经尝试过 Visual Studio 和 CodeBlocks :-(。我一直在努力让它工作 6 小时。我唯一的另一个想法是我的计算机不允许编译器访问该文件.
  • 最后一次尝试是您是否可以发布指向输入文件的链接。也许它会神奇地导致您的程序崩溃。在任何其他方面,它要么与操作系统相关,要么与编译器相关。 (虽然我认为代码块使用 minGW)
  • filedropper.com/playlist 是文件的链接。该文件的名称与我的代码中的名称不同,因为我正在测试。我终于能够显示它,但我仍然遇到同样的错误。我现在将尝试在 xCode 中运行,看看会发生什么。非常感谢您的帮助,非常感谢您的意见。
【解决方案2】:

readTextFile 函数不返回任何内容。您需要返回一个字符串。如果您收到错误what(): basic_string::_S_construct null not valid,那么这就是您的问题。您可以通过使用-Wall 编译器选项来避免类似的问题。

【讨论】:

    【解决方案3】:

    您使用std::string 来存储字符串,std::ifstream 用于从文件中读取,std::getline 用于读取单词……您真的应该使用std::vectors 而不是数组:

    typedef std::vector<std::string> Line;
    std::vector<Line> playList;
    

    它会让你的事情变得更容易。 我还建议您将读取文件的方式更改为:

    while(getline(...))
    {
        ...
    }
    

    但是由于不允许您使用std::vector,您的函数可能如下所示:

    // reads the content of input file and stores it into playList:
    void readTextFile(std::ifstream& infile, std::string playList[][5])
    {
        std::string line;
        for (int lineIndex = 0; getline(infile, line); ++lineIndex)
        {
            // skip empty lines:
            if (line.empty()) continue;
    
            std::string word;
            std::istringstream lineStream(line);
            for (int wordIndex = 0; getline(lineStream, word, '\t'); ++wordIndex)
            {
                // skip empty words:
                if (line.empty()) continue;
    
                playList[lineIndex][wordIndex] = word;
            }
        }
    }
    

    可以这样使用:

    std::string playList[19][5];
    
    std::ifstream infile("c:\\Test.txt");
    if (infile.is_open())
    {
        readTextFile(infile, playList);
        infile.close();
    }
    else
        std::cout << "Error Opening file" << std::endl;
    

    还要注意cout &lt;&lt; playList &lt;&lt; endl; 输出第一个字的地址。要打印所有单词,您必须编写一个循环。

    【讨论】:

    • 感谢您的快速回复!我目前正在学习一个非常基本的 C++ 编程课程,我们还没有涉及向量,所以我认为不幸的是我不能接受它们。
    • @Davidtftyfy:现在检查我的答案 :) 请注意,给定的解决方案依赖于文件中每行不超过 5 个单词的事实。
    • 好的,我试试看。感谢您为此付出的时间。我很惊讶人们在这个网站上有多么乐于助人,这是我的第一篇文章,所以我不知道会发生什么。
    • @Davidtftyfy:你会在这个网站上得到很好的答案......问题越好,你会得到更好和更合适的答案。只需阅读FAQSSCCE 和 Skeet 关于Writing the perfect question 的文章。
    • @Davidtftyfy:也可以看看Accepting Answers: How does it work? :)
    猜你喜欢
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多