【问题标题】:Reading text file per line in C++, with unknown line length在 C++ 中每行读取文本文件,行长未知
【发布时间】:2011-10-19 10:15:39
【问题描述】:

我有一个文本文件,格式如下:

1 3 4 5 6
6 7 8
4 12 16 17 18 19 20
20
0

一行可以包含 1 到 10000 个整数。我需要做的是逐行阅读所有这些。

这样的伪代码:

line=0;
i=0;
while(!file.eof()){
 while(!endLine){

 array[0][i++]=file.readChar();
 }
line++;i=0;
}

所以,我有一个数组,我想读取其中的每一行,并且每一行都包含这些整数中的每一个。

我遇到的问题是如何检查行尾是否已到。

注意,我不能使用字符串。

是的,这是作业,但作业的主要任务是构建一棵树,然后对其进行转换。我可以这样做,但我不知道如何从文件中读取整数。

【问题讨论】:

  • 如果作业的主要任务是建树,为什么不允许使用字符串?
  • 讲师在抽烟,我一定想试试。

标签: c++


【解决方案1】:

大概是这样的:

在读取一个 int 之后,我手动跳过了空格、制表符、回车和行尾(对于这个,你必须实现你的逻辑)。 要读取一个 int,我直接使用 ifstream 的 C++ 函数读取它。我不会逐个字符地阅读它,然后将其重新组合为字符串:-) 请注意,我将\r 跳过为“空格。对我来说,行尾是\n

#include <iostream>
#include <fstream>
#include <vector>

int main() 
{
    std::ifstream file("example.txt");

    std::vector<std::vector<int>> ints;

    bool insertNewLine = true;

    int oneInt;

    //The good() here is used to check the status of 
    //the opening of file and for the failures of
    //peek() and read() (used later to skip characters).
    while (file.good() && file >> oneInt)
    {
        if (insertNewLine)
        {
            std::vector<int> vc;
            ints.push_back(vc); 

            //With C++11 you can do this instead of the push_back
            //ints.emplace_back(std::vector<int>());

            insertNewLine = false;
        }

        ints.back().push_back(oneInt);

        std::cout << oneInt << " ";

        int ch;

        while ((ch = file.peek()) != std::char_traits<char>::eof())
        {
            if (ch == ' '|| ch == '\t' || ch == '\r' || ch == '\n')
            {
                char ch2;

                if (!file.read(&ch2, 1))
                {
                    break;
                }

                if (ch == '\n' && !insertNewLine)
                {
                    std::cout << std::endl;
                    insertNewLine = true;
                }
            }
            else
            {
                break;
            }
        }
    }

    //Here we should probably check if we exited for eof (good)
    //or for other file errors (bad! bad! bad!)

    return 0;
}

【讨论】:

  • 是的!这正是我需要的非常感谢!
  • 在结构方面比“C++”更多的是“C”答案(您可以轻松地将 std::ifstream 替换为 FILE*) - 您应该将解析逻辑和树构建逻辑封装到类中让它成为真正的 C++!
  • while(!myfile.eof()) 非常非常糟糕!搜索 SO 以了解原因。
  • 由于我输入文件中的最后一个文件总是一个 0,并且 0 不能出现在其他任何地方,我只是将其替换为 while(myInt!=0)
  • @Xeo 是的...我忘记了。找到 SO 文章更复杂 :-) 现在我使用 good
【解决方案2】:

有一个名为 getline() 的函数可以读取整行。 Link

【讨论】:

  • 操作员说Note, I can't use strings.
  • getline() 函数返回 char* 而不是字符串。
  • @Skizz:谁说std::string 必须和getline() 一起使用?如果您点击链接,您会看到答案指的是istream::getline,它采用普通的char* 和大小
  • 另外,getline 需要分配并传入一个数组,这意味着需要预先定义最大行长度。否则,您可能会将一行分成两半(更糟糕的是,将一个数字分成两半!)
  • 为什么你认为 OP 意味着 std::string? getline 为您提供一个以 nul 结尾的字符序列,通常称为字符串。
【解决方案3】:

您需要一个函数来从文件中读取值或指示行尾或文件结束条件,例如:

result_type GetNextValue (input_file, &value)
{
  if next thing in file is a number, set value and return number_type
  if next thing in file is an end of line, return end_of_line_type
  if end of file found, return end_of_file_type
}

然后你的数组构建循环变成:

line = 0
item = 0
eof = false

while (!eof)
{
  switch (GetNextValue (input_file, value))
  {
  case value_type: 
    array [line][item++] = value

  case end_of_line_type:
    line++;
    item = 0;

  case end_of_file_type:
    eof = true
  }
}

作为家庭作业,我会把细节留给你。

【讨论】:

  • 是的,但是我如何检查行尾是否已经到来? if next thing in file is an end of line, return end_of_line_type,我该如何检查?
  • @JanisPeisenieks:当您一次读取一个字符时,您会得到一个数字、一个空格或一个行尾字符。行尾字符很痛苦,因为有些系统使用 0x0a 后跟 0x0d,有些则相反,有些只使用其中一个。 GetNextValue 需要包含有关它到目前为止所读取内容的状态信息。更好的是,当您使用 C++ 时,它需要是一个对象,其中 input_file 作为构造函数参数,GetNextValue 作为成员函数(无需以这种方式传递任何参数)和一个额外的 GetReadValue。
【解决方案4】:

您可以读取 char 中的数字并检查 回车。下面给出了我刚刚尝试过的一个 sn-p:

ifstream ifile;  
ifile.open("a.txt");  
char ch;  
while((ch = ifile.get()) != EOF)  
{  
    std::cout<<ch<<"\n";  
    if (ch == '\n')  
        std::cout<<"Got New Line";  
}  
ifile.close();  

【讨论】:

    猜你喜欢
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2020-09-11
    • 1970-01-01
    相关资源
    最近更新 更多