Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获取txt文件中最后一行但不是空行_C++ - Fatal编程技术网

C++ 如何获取txt文件中最后一行但不是空行

C++ 如何获取txt文件中最后一行但不是空行,c++,C++,我想获取txt文件中的最后一行,但不是空行 这是我的代码: string line1, line2; ifstream myfile(argv[1]); if(myfile.is_open()) { while( !myfile.eof() ) { getline(myfile, line1); if( line1 != "" || line1 != "\t" || line1 != "\n" || !line1.empty() )

我想获取txt文件中的最后一行,但不是空行

这是我的代码:

string line1, line2;
ifstream myfile(argv[1]);
if(myfile.is_open())
{
    while( !myfile.eof() )
    {
        getline(myfile, line1);
        if( line1 != "" || line1 != "\t" || line1 != "\n" || !line1.empty() )
            line2 = line1;
    }
    myfile.close();
}
else
    cout << "Unable to open file";
字符串第1行,第2行;
ifstream myfile(argv[1]);
如果(myfile.is_open())
{
而(!myfile.eof())
{
getline(myfile,第1行);
如果(第1行!=“”| |第1行!=“\t”| |第1行!=“\n”| |!第1行。空()
line2=line1;
}
myfile.close();
}
其他的

好的,让我们从明显的部分开始。这:
而(!myfile.eof())
基本上总是错误的,因此无法正确检测文件的结尾。由于您正在使用
getline
读取数据,因此需要检查其返回值:

while (getline(myfile, line1)) // ...
同样,这里的逻辑是:

    if( line1 != "" || line1 != "\t" || line1 != "\n" || !line1.empty() )
        line2 = line1;

…显然是错误的。我猜你真的想要
&&
而不是
|
来做这个。目前,结果总是正确的,因为无论
line1
包含什么值,它都必须至少与这些值中的一个不相等(即,它不能同时只包含一个制表符和一个新行,并且不包含任何内容,但这是结果为假所必需的)。测试两个
!line1.empty()
line1!=“
也显得多余。

仅将| |更改为&&来检查行是否为空是不够的。如果有七个空格,一个制表符,另外三个空格,最后一个换行符呢?不能列出一行中仅获取空白的所有方法。相反,检查行中的每个字符是否为空白

在此代码中,如果在行中发现任何非空格字符,
为空
将为false

bool is_empty = true;
for (int i = 0; i < line.size(); i++) {
    char ch = line[i];
    is_empty = is_empty && isspace(ch);
}
bool为空=真;
对于(int i=0;i
完整解决方案:

#include <iostream>
#include <fstream>
#include <cctype>
#include <string>

using namespace std;

int main(int argc, char* argv[]) {
    string line;
    string last_line;

    ifstream myfile(argv[1]);
    if(myfile.is_open())
    {
        while( getline(myfile, line) ) {
            bool is_empty = true;
            for (int i = 0; i < line.size(); i++) {
                char ch = line[i];
                is_empty = is_empty && isspace(ch);
            }
            if (!is_empty) {
                last_line = line;
            }
        }
        myfile.close();
        cout << "Last line: " << last_line << endl;
    }
    else {
        cout << "Unable to open file";
    }   

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,char*argv[]){
弦线;
字符串最后一行;
ifstream myfile(argv[1]);
如果(myfile.is_open())
{
while(getline(myfile,line)){
bool为空=真;
对于(int i=0;icout为什么不向后读取文件?这样你就不必扫描整个文件来完成这项工作。看起来这应该是可能的

int main(int argc, char **argv)
{
   std::cout<<"Opening "<<fn<<std::endl;
   std::fstream fin(fn.c_str(), std::ios_base::in);
   //go to end
   fin.seekg(0, std::ios_base::end);
   int currpos = fin.tellg();
   //go to 1 before end of file
   if(currpos > 0)
   {
       //collect the chars here...
       std::vector<char> chars;
       fin.seekg(currpos - 1);
       currpos = fin.tellg();
       while(currpos > 0)
       {
           char c = fin.get();
           if(!fin.good())
           {
               break;
           }
           chars.push_back(c);
           currpos -= 1;
           fin.seekg(currpos);
       }
       //do whatever u want with chars...
       //this is the reversed order
       for(std::vector<char>::size_type i = 0; i < chars.size(); ++i)
       {
           std::cout<<chars[i];
       }
       //this is the forward order...
       for(std::vector<char>::size_type i = chars.size(); i != 0; --i)
       {
           std::cout<<chars[i-1];
       }
   }
   return 0;
}
int main(int argc,char**argv)
{

std::cout除了其他人所说的以外:
在调用
std::getline()
之前,可以通过执行
myfile>>std::ws
避免读取空格。这将消耗所有前导空格


然后,您的条件降低到
!line1.empty()
。当该行只包含几个空格时,这也会起作用,因为您的版本会失败。

我无法通过谷歌搜索适当的get_last_line函数来满足我的需要,以下是我的想法。您甚至可以通过调用instream get_last_line函数来读取多个非空的最后一行,而无需重置seek呃,它只支持1个字符的文件。我添加了reset参数,可以将其设置为ios_base::end,以允许在读取最后一行后进行输出操作


您的文件读取逻辑不正确。总而言之,只有在您尝试读取后才设置标志,在读取前检查
eof
“向后”。流仍然会重载转换运算符,因此您应该始终使用
if(myfile)检查流状态
。还请注意,当getline读取一行(以“\n”结尾)时,它将永远不会包含“\n”。终止字符不会添加到字符串(第1行)。是的,非常好的解决方案。非常感谢。如何,您有什么建议吗?谢谢
std::string& get_last_line(
        std::istream& in_stream, 
        std::string& output = std::string(), 
        std::ios_base::seekdir reset = std::ios_base::cur)
{
    output.clear();
    std::streambuf& buf = *in_stream.rdbuf();
    bool text_found = false;

    while(buf.pubseekoff(-1, std::ios_base::cur) >= 0)
    {
        char c = buf.sgetc();
        if(!isspace(c))
            text_found = true;
        if(text_found)
        {
            if(c == '\n' || c == -1)
                break;
            output.insert(0, sizeof c, c);
        }
    }

    buf.pubseekoff(0, reset);
    return output;
}

std::string& get_last_line(
        const std::string& file_name, 
        std::string& output = std::string())
{
    std::ifstream file_in(
        file_name.c_str(), 
        std::ios_base::in | std::ios_base::ate);
    if(!file_in.is_open())
    {
        output.clear();
        return output;
    }
    get_last_line(file_in, output);
    file_in.close();
    return output;
}