简体   繁体   English

从C ++文件中读取数字

[英]Reading numbers from a file in C++

I want to get numbers from a text file by reading it symbol by symbol and output the numbers in another file. 我想通过逐个符号读取文本文件来获取数字,然后将数字输出到另一个文件中。

Number - a word which consists only of numeric symbols. 数字-仅由数字符号组成的单词。

Word - any string of symbols which is separated by dot, comma, brackets, exclamation mark, question mark or line break. 单词-用点,逗号,方括号,感叹号,问号或换行符分隔的任何符号字符串。

For example from file 例如来自文件

in.txt: in.txt:

masnd kasjd k!1234 564,7
7.,43, mb?? 67hh k4k 87 90.

I want to output 我想输出

out.txt out.txt

1234
564
7
7
43
87
90

I tried to read the whole word to check if the word is a number, and if it is put the 'cursor' in the beginning of the word and output it in the out.txt 我试图读取整个单词以检查单词是否为数字,以及是否将“光标”放在单词的开头并将其输出到out.txt中

I somewhere messed up and all I get in the out.txt file is 我在某个地方搞砸了,所有进入out.txt文件的内容都是

out.txt out.txt

234
64

7
87
90

And also if I don't put a separating symbol in the end of the in.txt file it stucks in a loop somewhere, and when I close the program and try to open the out.txs file, notepad crushes 另外,如果我没有在in.txt文件的末尾放置分隔符号,它会陷入循环中的某个位置,并且当我关闭程序并尝试打开out.txs文件时,记事本会崩溃

This is how far i have made it 这是我走了多远

#include <iostream>
#include <cctype>
#include <fstream>
using namespace std;
bool isStop(char c);
int main(){
    fstream fin;
    fstream fout;
    streampos p;
    char a,b=' ';
    fin.open("in.txt", ios::in);
    fout.open("out.txt", ios::out);
    fin.get(a);
    while(!fin.eof()){
        if(isdigit(a) && isStop(b)){
            p=fin.tellg();
            while(isdigit(a) && !fin.eof()){
            fin.get(a);
            }
            if(isStop(a) || fin.eof()){
                fin.seekg(p-1, ios::beg);
                fin.get(a);
                while(isdigit(a) && !fin.eof()){
                    fout.put(a);
                    fin.get(a);
                }
                fout.put('\n');
            }
        }
        b=a;
        fin.get(a);
    }
    fin.close();
    fout.close();
    return 0;
}
bool isStop(char c)
{
    return (c==' ' || c=='.' || c==',' || c=='(' || c==')' || c=='!' ||                             c=='?' || c=='\n');
}

I suspect your issue stems from a couple of things, like treating the space character as the only whitespace character (when there could be newlines '\\n' , tabs '\\t' , or carriage returns '\\r' ), and additionally using !fin.eof() as a loop check. 我怀疑您的问题是由两方面原因引起的,例如将空格字符视为唯一的空白字符(可能存在换行符'\\n' ,制表符'\\t'或回车符'\\r' ),以及另外使用!fin.eof()作为循环检查。

In fact, All the jumping around in the file appears unnecessary and difficult to read. 实际上,文件中的所有跳转似乎都是不必要的,而且很难阅读。

I propose the following simplified algorithm (much more C++-esque): 我提出以下简化算法(更多的C ++风格):

  • Read a line 读一行

  • Parse the line into words 将行解析为单词

  • Verify a word is a valid number (according to your rules) 验证单词是否为有效数字(根据您的规则)

  • if valid, write that number to file 如果有效,将该数字写入文件

Here's one possible implementation (using cin and cout instead of files): 这是一种可能的实现(使用cincout代替文件):


Define your separators: 定义分隔符:

const std::string separators = ",.()! \t";

Read a line: 读一行:

std::string next;
while(getline(std::cin, next))
{

Break it into words: 将其分解为文字:

    std::string::iterator beg = std::begin(next);
    while(beg != std::end(next))
    {
        beg = std::find_if(beg, std::end(next), [](char c)
        {
            return std::isdigit(c);
        });

        std::string::iterator end = std::find_if(beg, std::end(next), [](char c)
        {
            return separators.find(c) != std::string::npos;
        });

        // now we have digit to separator (or end of string). So long as elements between beg (inclusive) and end(exclusive) are all digits, we're good

Verify the word is all digits from first digit to next separator: 验证单词是从第一个数字到下一个分隔符的所有数字:

        std::string::iterator it = beg;
        for(; it != end && isdigit(*it); ++it)
        {}

If verification passes, write to file: 如果验证通过,请写入文件:

        if (it == end) // they're all digits
        {
            std::cout << std::string(beg, end) << std::endl;
        }
        beg = end;
    } // end while loop (word separation)
} // end while loop (reading lines)

Live Demo 现场演示

A bit more c++ like: 更多c ++,例如:

#include <fstream>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;
// string of separators 
static const string valid = ".,!? \n\0'";   

// check whether a character is in the separator
static bool isValid(char c) { 
  return (find(valid.begin(), valid.end(), c) != valid.end());
}

int main() {
  // open your input/output files
  ifstream inputf("./in.txt");
  ofstream outf("./out.txt");
  // save your input in a string
  string file((istreambuf_iterator<char>(inputf)), (istreambuf_iterator<char>()));
  int beg; // start of a number (index)
  std::string nb;
  // iterate over your string
  for (int i = 0; i < file.size() ;) {
    // while your char is an alpha char, do nothing
    while (isdigit(file[i]) == false) ++i;
    nb = "";
    beg = i;
    // search for a number
    while (isdigit(file[i]) == true)
      nb += file[i++];
    // check if the current number can be saved in the output file
    if (nb != "" && isValid(file[i]) && (beg == 0 || isValid(file[beg - 1])))
      outf << nb << "\n";
  }
  inputf.close(); outf.close();
}

And then your output file: 然后您的输出文件:

$> cat out.txt 
1234
564
7
7
43
87
90

I had to check the file symbol by symbol so I couldn't use getline, but in the end I figured it all out. 我必须逐个符号地检查文件,所以我不能使用getline,但是最后我弄清楚了所有内容。

I saved the word in a string and afterwards checked if it was a number and if it was, i put it in the out file. 我将单词保存在字符串中,然后检查它是否为数字,如果是,则将其放入out文件中。

Here is the code: 这是代码:

#include <iostream>
#include <fstream>
using namespace std;
bool isStop(char c);
int main(){
    fstream fin;
    fstream fout;
    string s;
    char a,b=' ';
    fin.open("inF20.txt", ios::in);
    fout.open("outF20.txt", ios::out);
    while(fin.get(a)){
        if(isdigit(a) && isStop(b)){
                s+=a;
            while(fin.get(a) && isdigit(a)){
                s+=a;
            }
            if(isStop(a) || fin.eof()){
                for(int i=0;i<s.length();i++){
                    fout.put(s[i]);
                }
                fout.put('\n');
            }
        }
        s.clear();
        b=a;
    }
    fin.close();
    fout.close();
    return 0;
}
bool isStop(char c)
{
    return (c==' ' || c=='.' || c==',' || c=='(' || c==')' || c=='!' || c=='?' || c=='\n');
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM