在C++中有没有一种方法可以从文本文件中删除/修剪尾随的新行?例如
content content content content content content <- this line in the text file is empty and needs to go ->
kninwzqo1#
当然!一种方法是read the file to a std::string
#include <fstream> #include <string> // Add this code inside your main() function std::ifstream ifs("filename.txt"); std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
然后使用此处描述的任何技术:C++ Remove new line from multiline string然后你可以用新的结果覆盖这个文件。当然,这种方法在处理非常大的文件(比如说2GB)时是不实用的,但是根据你最初的问题,这样的事情并不是一个约束。这个thread在检测新线路方面也有很好的素材。
nkcskrwz2#
ifstream fin("input.txt"); vector<string> vs; string s; while(getline(fin,s)) vs.push_back(s); fin.close(); ofstream fout("input.txt"); for(vector<string>::iterator it = vs.begin(); it != vs.end(); ++it) { if(it != vs.begin()) fout << '\n'; fout << *it; }
lp0sw83n3#
最有效的方法是查找文件末尾并将文件末尾指针向后移动。不幸的是,这是不可移植的,因为在C或C++标准库中都没有设置文件末尾指针的标准方法。您需要使用特定于平台的函数,如Windows上的SetEndOfFile或POSIX上的ftruncate。例如:
SetEndOfFile
ftruncate
void RemoveFinalNewline(const char *filename) { #if defined(_WIN32) HANDLE hFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) ; // handle error LARGE_INTEGER fileSize; if(GetFileSizeEx(hFile, &fileSize) == 0) ; // handle error if(fileSize.QuadPart < 2) ; // this case is left as an exercise to the reader LARGE_INTEGER newFilePtr; newFilePtr.QuadPart = -2; if(SetFilePointerEx(hFile, &newFilePtr, NULL, FILE_END) == 0) ; // handle error char lastTwoBytes[2]; if(ReadFile(hFile, lastTwoBytes, 2, NULL, NULL) == 0) ; // handle error if(lastTwoBytes[1] == '\n') { fileSize.QuadPart--; if(lastTwoBytes[0] == '\r') fileSize.QuadPart--; if(SetFilePointerEx(hFile, &fileSize, NULL, FILE_BEGIN) == 0) ; // handle error if(SetEndOfFile(hFile) == 0) ; // handle error // Success! } // else the file didn't end in a newline CloseHandle(hFile); // and we're done #else // POSIX case; the non-Windows, non-POSIX case is left as an exercise int fd = open(filename, O_RDWR); if(fd == -1) ; // handle error off_t fileSizeMinus1 = lseek(fd, -1, SEEK_END); if(fileSizeMinus1 == (off_t)-1) ; // handle error // We're assuming that a newline is a bare LF '\n' here. The CRLF case // is left as an exercise (hint: see the Windows case above) char lastChar; if(read(fd, &lastChar, 1) != 1) ; // handle error if(lastChar == '\n') { if(ftruncate(fd, fileSizeMinus1) == -1) ; // handle error // else success! } // else the file does not end in a newline close(fd); // and we're done #endif }
sgtfey8w4#
C++11或更高版本-删除尾随 * 空格 *(换行符、制表符、空格等):
std::string readAndTrimTrailingSpaces(std::string const & filePath) { std::ifstream file(filePath); std::string buffer(std::istreambuf_iterator<char>{file}, {}); while (!buffer.empty() && std::isspace(buffer.back())) buffer.pop_back(); return buffer; }
mu0hgdu05#
您需要从文件中读取所有内容,然后以不存在空行的方式或您想要的方式再次写入内容。
qyyhg6bp6#
您可以创建一个简单的过滤器,应用如下:
remove_empty_last_line < input.txt > output.txt
或者,您可以创建自己的文件输入流ala:
#include <fstream> std::ifstream myin(filename);
然后,代码将类似于(未经测试)...
char c, d, e; if (cin.get(c)) if (cin.get(d)) { while (cin.get(e)) { cout << d; c = d; d = e; } if (c != '\n' || d != '\n') cout << d; } else cout << c;
(如果需要的话,用myin替换cin,然后用myin.close())。对于如此简单的内容,不需要使用std::string:它们只会让一切都慢下来。C(因此C++)的一大优点就是能够一次一个字符地高效处理数据。
6条答案
按热度按时间kninwzqo1#
当然!一种方法是read the file to a std::string
然后使用此处描述的任何技术:
C++ Remove new line from multiline string
然后你可以用新的结果覆盖这个文件。当然,这种方法在处理非常大的文件(比如说2GB)时是不实用的,但是根据你最初的问题,这样的事情并不是一个约束。
这个thread在检测新线路方面也有很好的素材。
nkcskrwz2#
lp0sw83n3#
最有效的方法是查找文件末尾并将文件末尾指针向后移动。不幸的是,这是不可移植的,因为在C或C++标准库中都没有设置文件末尾指针的标准方法。您需要使用特定于平台的函数,如Windows上的
SetEndOfFile
或POSIX上的ftruncate
。例如:sgtfey8w4#
C++11或更高版本-删除尾随 * 空格 *(换行符、制表符、空格等):
mu0hgdu05#
您需要从文件中读取所有内容,然后以不存在空行的方式或您想要的方式再次写入内容。
qyyhg6bp6#
您可以创建一个简单的过滤器,应用如下:
或者,您可以创建自己的文件输入流ala:
然后,代码将类似于(未经测试)...
(如果需要的话,用myin替换cin,然后用myin.close())。对于如此简单的内容,不需要使用std::string:它们只会让一切都慢下来。C(因此C++)的一大优点就是能够一次一个字符地高效处理数据。