C++文本文件输入

C++ Text File Input

本文关键字:输入 文件 文本 C++      更新时间:2023-10-16

这是一个相对简单的问题,但我似乎找不到答案。 我需要从文本文件中读取每个字符,不包括空格

我目前有:

fstream inFile(fileName, ios::in);
char ch;
while (!inFile.eof()){
ch = inFile.get();

这适用于所有字母和数字,但不适用于特殊字符。 除了空格之外,我可以使用什么替代方法来读取所有内容?

假设文件是 ASCII 并且不包含 NULL 字符,则可以使用以下方法。

size_t ReadAllChars(char const* fileName, char **ppDestination)
{
//Check inputs
if(!filename || !ppDestination)
{
//Handle errors;
return 0;
}
//open file for reading
FILE *pFile = fopen(fileName, "rb");
//check file successfully opened
if(!pFile)
{
//Handle error
return 0;
}
//Seek to end of file (to get file length)
if(_fseeki64(pFile, 0, SEEK_END))
{
//Handle error
return 0;
}
//Get file length
size_t fileLength = _ftelli64(pFile);
if(fileLength == -1)
{
//Handle error
return 0;
}
//Seek back to start of file
if(_fseeki64(pFile, 0, SEEK_SET))
{
//Handle error
return 0;
}
//Allocate memory to store entire contents of file
char *pRawSource = (char*)malloc(fileLength);
//Check that allocation succeeded
if(!pRawSource)
{
//Handle error
//return 0;
}
//Read entire file
if(fread(pRawSource, 1, fileLength, pFile) != fileLength))
{
//Handle error
fclose(pFile);
free(pRawSource);
return 0;
}
//Close file
fclose(pFile);
//count spaces
size_t spaceCount = 0;
for(size_t i = 0; i < fileLength; i++)
{
if(pRawSource[i] == ' ')
++spaceCount;
}
//allocate space for file contents not including spaces (plus a null terminator)
size_t resultLength = fileLength - spaceCount;
char *pResult = (char*)malloc(resultLength + 1)
//Check allocation succeeded
if(!pResult)
{
//Handle error
free(pRawSource);
return 0;
}
//Null terminate result
pResult[resultLength] = NULL;
//copy all characters except space into pResult
char *pNextTarget = pResult;
for(size_t i = 0; i < fileLength; i++)
{
if(pRawSource[i] != ' ')
{
*pNextTarget = pRawSource[i];
++pNextTarget;
}
}
//Free temporary buffer
free(pRawSource);
*ppDestination = pResult;
return resultLength;
}

您应该以二进制模式打开文件

一种更简单的方法就是开始检查您正在迭代的所有字符的 ASCII。 如果字符的 ASCII 值为"20"(ASCII 表示空格(,则用"继续"跳过它,否则只需打印它。

假设您使用的是默认区域设置C++,也许尝试将它们放入std::string中,让std::ifstream& operator >> (std::ifstream&, std::string&)std::skipws为您施展魔法(跳过所有空格(?

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <utility>
int main(int, char* argv[]) 
{
const char *filename = /* filename */;
std::ifstream in{filename};
if (in.fail()) {
std::cerr << "Fails to open " << filename << std::endl;
return 1;
}
/*
* Actually, you can skip this line, because the default behavior of 
* std::fstream and other stream is to skip all the white space before input.
*/
in >> std::skipws;
std::vector<std::string> stringv;
// reserve to speed up, you can replace the new_cap with your guess
stringv.reserve(10);
std::string str;
/*
* while std::skipws tells the stream to skip all the white space before input, 
* std::ifstream& operator >> (std::ifstream&, std::string&) will stop when a space is read.
*/
while(in >> str)   
stringv.push_back(std::move(str));
}

编辑:

我还没有测试过这个程序,所以可能会有一些编译错误,但我非常确定这种方法应该有效。

使用!in.eof()测试是否达到 eof,但不测试提取是否成功,这意味着您可以获得无效数据。in >> str修复此问题,因为在提取后,!in.fail()的值指示从流中提取是否成功。