Jon
Jon

Reputation: 1801

Reading in multiple text strings of various lengths with C++

I have a bunch of ASCII based text files that are used as input files into various computer programs and I need to convert them to a different format. Each input file starts with a 4 digit number and is then either followed by further input data or comment lines if the first four digit number begins with a 0 (number zero). I am developing a C++ based file convertor and I would like it to read in the four digit number and if that number is a zero read in the comment lines that follow it. An example is provided below. C++ can easily read in the numbers as an array or by using std::vector; however reading in the character string gets to be much more complex. First of all if each comment line had the same number of words, I could treat each string as if it were filling its own line within a fixed column, but since each comment line has a different number of words, then the number of columns to be read in at each line would be different. Is there a simple way to read in the comment lines where C++ will not see the space between each word as the end of one column of data and the beginning of another? Generic numbers and data are used in the file example below, but hopefully you can see that the comment lines starting with the number 0 have a different number of words following them, making it impossible to read the file in as a serious of data columns.

0001 Input File Name
0001 - Description of input file goes here
0001 - PROGRAM name that works on this data
0000 ==========================================
0001 List of references used in the development of this input file
0001 [1] Ref. 1
0001 [2] Ref. 2
0001 [3] Ref. 3
1100 Input line 1:       CBRD 1-0220
1101 Core Length (mm):   8.189
1102 Core diameter (mm): 37.81

Upvotes: 0

Views: 1192

Answers (2)

learningToCode
learningToCode

Reputation: 63

Use getline function to read a line from the file to a string and work on that string to do whatever you want.

Something like: while(getline(file, string)) { ... }

You don't need to know max chars per line. This is simply what I meant:

 int main() {
      std::fstream iFile("Input.txt", std::fstream::in);
      //You might want to check if it is open
      std::string line;

      int firstNumber;
      std::string word;
      while(getline(iFile, line)){
        std::stringstream lineStream(line);

        lineStream >> firstNumber;
        if(firstNumber == 0) { // modify based on what you want to do
          while(lineStream >> word) {
            std::cout << word << " ";
          }
        }
      }
      std::cout << std::endl;
      iFile.close();
    }

Upvotes: 2

Jon
Jon

Reputation: 1801

Based on the suggestions provided above, I was able to implement the following solution. I will try to clean it up and make it more generic so it can be applied easily to other problems. I appreciate the suggestions and the help it gave me.

#include <iostream>
#include <fstream>
#include <cstring>
#include <stdio.h>

int main(int argc, const char * argv[]) {

    std::string Input_File("Input.txt");
    std::string comment;
    const int MAX_CHARS_PER_LINE = 1200;
    const int MAX_TOKENS_PER_LINE = 40;
    const char* const DELIMITER = " ";
    FILE *Output_File;

    std::ifstream inp(Input_File, std::ios::in | std::ios::binary);
    if(!inp) {
        std::cout << "Cannot Open " << Input_File << std::endl;
        return 1; // Terminate program
    }

    Output_File = fopen ("Output_File.txt","w");
    std::ofstream out("Output_File.txt", std::ios::in | std::ios::binary);

    // read each line of the file
    while (!inp.eof())
    {
        // read an entire line into memory
        char buf[MAX_CHARS_PER_LINE];
        inp.getline(buf, MAX_CHARS_PER_LINE);

        // parse the line into blank-delimited tokens
        int n = 0; // a for-loop index

        // array to store memory addresses of the tokens in buf
        const char* token[MAX_TOKENS_PER_LINE] = {}; // initialize to 0

        // parse the line
        token[0] = strtok(buf, DELIMITER); // first token
        if (token[0]) // zero if line is blank
        {
            for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
            {
                token[n] = strtok(0, DELIMITER); // subsequent tokens
                if (!token[n]) break; // no more tokens
            }
            if (strncmp (token[0],"0",1) == 0)
            {
                for(int i = 0; i < n; i++) out << token[i] << " ";
            }
            out << std::endl;
        }
    }
    inp.close();

    return 0;
}

Upvotes: 0

Related Questions