简体   繁体   中英

Reading a file with c++ containing chars and numbers

I have a text file containing sort of a graph presentation, as such:

7

{5, 2, 3}, {1,5}, { }, { }, {3}, { }, { }

Now, I know how to read a file and get in into an int

    while ((n = myfile.get()) != EOF) 

or into a string line by line

    getline (myfile,line)

The problem I have, is that with both of these options I can't really seem to compare every character I extract and check if it's a number or a "," or "{" or "}". Is there a simple way of doing that? I've been banging my head with this for hours since yesterday. I've tried some isdigit and casting, but that didn't work for me as well and really complicated stuff.

The easiest solution, I think, would be to get your hands dirty a bit, by reading the file char by char. I suggest you store the sets in a vector of vectors of int s (visualize it like a 2D array, a matrix, if you like).

If the i-th set is empty, then the i-th vector will be empty too.

In the loop in which you will parse the characters, you will skip the opening curly braces and commas. You will do similarly for the closing curly braces, except from the fact that you would need to update an index, which will help us update the index-th vector.

When we actually read a digit, then you can convert a char to an int .

Complete example:

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

int main(void) {
    char ch;
    fstream fin("test.txt", fstream::in);
    if(!fin) {
        cerr << "Something is wrong...! Exiting..." << endl;
        return -1;
    }
    int N; // number of sets
    fin >> N;
    vector<vector<int> > v;
    v.resize(N);
    int i = 0;
    while (fin >> ch) {
            //cout << ch << endl;
        if(ch == '{' || ch == ',')
            continue;
        if(ch == '}') {
            i++;
            continue;
        }
        v[i].push_back(ch - '0');
    }
    if(i == N) {
        cout << "Parsing the file completed successfully." << endl;
    } else {
        cout << "Parsed only " << i << " sets, instead of " << N << endl;
    }
    for(size_t i = 0; i < v.size(); ++i) {
        if(v[i].size() == 0)
            cout << i + 1 << "-th set is empty\n";
        else {
            for(size_t j = 0; j < v[i].size(); ++j)
                cout << v[i][j] << " ";
            cout << endl;
        }
    }
    return 0;
}

Output:

gsamaras@aristotelis:/Storage/homes/gsamaras$ g++ main.cpp

gsamaras@aristotelis:/Storage/homes/gsamaras$ ./a.out 
Parsing the file completed successfully.
5 2 3 
1 5 
3-th set is empty
4-th set is empty
3 
6-th set is empty
7-th set is empty

Important note: This should serve as a starting point, since it won't treat numbers that have more than one digits. In this case, you will to read up to the comma, or the closing curly brace, to make sure that you read all the digits of the numbers, then convert from string to integer, and then store it in the corresponding vector.

Its better to read character by character as follows:

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

int main()
{
    string line;
    int lineNum = 0;
    ifstream myfile ("file.txt");
    if (myfile.is_open())
    {
        while ( getline (myfile, line) )
        {
            // Identifying the type of charcter
            char a;
            cout << "Line Number " << ++lineNum << ": ";
            for(int i = 0; i < line.length(); i++)
            {
                a = line[i];
                cout << "\n\t" << a;
                if((a >= 32 && a <= 47) || (a >= 58 && a <= 64) || (a >= 91 && a <= 96) || (a >= 123 && a <= 126))
                {
                    cout << "\t(This character is either a Punctuation or arithmetic mark.)";
                    // If you don't want to porcess these character, then you may 'continue' to the next sub string
                }
                else if(a >= 48 && a <= 57)
                {
                    cout << "\t(This character is a number.)";
                    // If you want to change the number ot int, you can use atoi or stoi
                }
                else if(a >= 65 && a <= 90)
                    cout << "\t(Capital letter)";
                else if(a >= 97 && a <= 122)
                    cout << "\t(Small letter)";

            }
            cout<<endl;
        }
        myfile.close();
    }
    else
        cout << "Unable to open file";
    return 0;
}

I hop this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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