【问题标题】:C++ how to remove all chars and special characters from a fileC ++如何从文件中删除所有字符和特殊字符
【发布时间】:2016-08-31 19:50:15
【问题描述】:

我已经看到如何从字符串中删除特定字符,但我不确定如何在打开文件的情况下执行此操作,或者您是否可以这样做。基本上一个文件会打开,里面有任何东西,我的目标是删除所有可能出现的字母 a-z、特殊字符和空格,这样剩下的就是我的数字。当文件打开时,您能否轻松删除所有字符而不是指定 a、b、c 等,或者我是否必须将其转换为字符串?在内存中这样做会更好吗?

我的代码如下:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    string filename;
    cout << "Enter the name of the data file to open" << endl;
    cin >> filename >> endl;

    ofstream myfile;
    myfile.open(filename);

    if (myfile.is_open()) { //if file is open then

        while(!myfile.eof()){ //while not end of file
                                //remove all chars, special and whitespace
        }
    }
    else{
        cout << "Error in opening file" << endl;
    }
        return 0;
}

【问题讨论】:

  • 为什么不只提取使用isdigit() 的数字而忽略其他所有内容呢?
  • 然后,一旦你读入一个字符串,只需获取所有数字字符并将它们写回一个单独的文件。
  • @FirstStep 我只提取数字会弄乱格式吗?这就是为什么我决定不这样做。因为一行可能是 272 而下一行是 345 我不希望它变成 272345
  • @user5468794 但是你说你想删除所有的空格???

标签: c++ char fstream


【解决方案1】:

前言

如果我理解得很好,您只想保留数字。也许保留 ascii 数字的字符并消除其他字符比消除许多其他字符类并希望其余的只是数字更容易。

也永远不要循环 eof 来读取文件。而是在流上循环。

最后,您应该读取ifstream 并写入ofstream

第一种方法:读取字符串

您可以逐行读取/写入文件。您需要足够的内存来存储最大的行,但您会受益于缓冲效果。

if (myfile.is_open()) { //if file is open then
    string line;
    while(getline(myfile, line)){ //while succesful read
        line.erase(remove_if(line.begin(), line.end(), [](const char& c) { return !isdigit(c); } ), line.end()); 
        ... // then write the line in the output file 
    }
}
else ...

Online demo

第二种方法:读取字符

您可以逐个字符地读取/写入字符,这为处理单个字符(切换字符串标志等)提供了非常灵活的选项。您也可以从缓冲中受益,但是每个字符都有函数调用开销。

if (myfile) { //if file is open then
    int c; 
    while((c = myfile.get())!=EOF){ //while succesful read
                        //remove all chars, special and whitespace
        if (isdigit(c) || c=='\n') 
            ... .put(c); // then write the line in the output file 
    }
}
else ...

Online demo

其他方法

您还可以读取一个固定大小的大缓冲区,并像处理字符串一样进行操作(但不要消除 LF)。优点是内存需求不受文件中一些非常大的行的影响。

您还可以确定文件大小,并尝试一次读取整个文件(或以非常大的块)。然后,您将以内存消耗为代价最大化性能。

【讨论】:

    【解决方案2】:

    这只是一个示例,用于使用专用过滤器从文件中提取所需的所有字符:

    std::string get_purged_file(const std::string& filename) {
      std::string strbuffer;
      std::ifstream infile;
    
      infile.open(filename, std::ios_base::in);
      if (infile.fail()) {
        // throw an error
      }
    
      char c;
      while ((infile >> c).eof() == false) {
        if (std::isdigit(c) || c == '.') {
          strbuffer.push_back(c);
        }
      }
    
      infile.close();
      return strbuffer;
    }
    

    注意:这只是一个例子,它必须经过优化。只是给你一个想法:

    • 一次读取多个字符(使用适当的缓冲区)。
    • 在字符串中保留内存。

    “清除”缓冲区后,您可以在将内容保存到另一个文件时覆盖您的文件。

    【讨论】:

    • @FirstStep 我无法得到它。答案是 “因为 iostream::eof 只会在读取流的末尾后返回 true。它并不表示下一次读取将是流的末尾。” 但这并不影响我的代码,那你是什么意思?
    • @FirstStep 请赐教。
    • EOF 测试的最坏情况(通常是错误的):while ((infile &gt;&gt; c).eof() == false)
    • @DieterLücking 我没明白。什么意思?
    猜你喜欢
    • 2014-02-22
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2012-05-04
    • 2016-08-23
    相关资源
    最近更新 更多