0

I Developed some code below which will pull entries from a list and build a series of entries for later use. The list I used and code is below.

Using the ifstream function, I grab characters from the list and every time the code reaches a next line character or \n, the code will compile the text, build the string and move to the next line.

Is this efficient for pulling from a txt file, It works but feels inefficient.

Text file list

name
title
year
manufacturer
developer
genre
cloneOf
players
ctrltype
buttons
joyways
rating
score

Current code I am trying to optomize

#include "pch.h"
#include <iostream>
#include <string>
#include <fstream>


std::string sql;
std::string Entryname;
std::string Entryappends;

int main()
{
    std::ifstream MetaEntries ("c:\\CodeRepo/List.txt", std::ifstream::in);
    sql.append("CREATE TABLE IF NOT EXISTS Meta(");
    sql.append("collectionName TEXT KEY,");

    char c = MetaEntries.get();

    while (MetaEntries.good()) {
        if (c == '\n') {
            Entryappends = std::string(" TEXT NOT NULL DEFAULT '', ");
            sql.append(Entryname + Entryappends);
            Entryname.clear();
        }

        Entryname += c;
        c = MetaEntries.get();
//      std::cout << Entryname;
    }

    MetaEntries.close();
    Entryappends = std::string(" TEXT NOT NULL DEFAULT '';");
    sql.append(Entryname + Entryappends);

    sql.append("CREATE UNIQUE INDEX IF NOT EXISTS MetaUniqueId ON Meta(collectionName, name);");
    std::cout << sql;

    return 0;
}

output: Pretty much it works exactly as intended.

CREATE TABLE IF NOT EXISTS Meta(collectionName TEXT KEY,name TEXT NOT NULL DEFAULT '',
title TEXT NOT NULL DEFAULT '',
year TEXT NOT NULL DEFAULT '',
manufacturer TEXT NOT NULL DEFAULT '',
developer TEXT NOT NULL DEFAULT '',
genre TEXT NOT NULL DEFAULT '',
cloneOf TEXT NOT NULL DEFAULT '',
players TEXT NOT NULL DEFAULT '',
ctrltype TEXT NOT NULL DEFAULT '',
buttons TEXT NOT NULL DEFAULT '',
joyways TEXT NOT NULL DEFAULT '',
rating TEXT NOT NULL DEFAULT '',
score TEXT NOT NULL DEFAULT '';CREATE UNIQUE INDEX IF NOT EXISTS MetaUniqueId ON Meta(collectionName, name);
Hojo.Timberwolf
  • 836
  • 8
  • 27
  • 2
    Why don't you [read line by line](https://en.cppreference.com/w/cpp/string/basic_string/getline) instead? Also please read [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong), your `while (MetaEntries.good())` is just the same. – Some programmer dude Mar 29 '19 at 10:09
  • 1
    Use `getline`. It's probably not going to be any more *efficient* (nothing wrong with your code efficiency wise) but much more importantly it's going to be more *clear* what your code is doing. – john Mar 29 '19 at 10:12

2 Answers2

3

I think you can try to read word by word or, given the structure of your text file, even line by line. Hope this helps.

Theodor Badea
  • 465
  • 2
  • 9
1

You can use getline

[...]
std::ifstream metaEntries ("c:\\CodeRepo/List.txt", std::ifstream::in);
sql.append("CREATE TABLE IF NOT EXISTS Meta(");
sql.append("collectionName TEXT KEY,");

string line = "";
while (std::getline(metaEntries, line)) {
    // don't use global variables. This should probably be a constant:
    std::string entryAppends = std::string(" TEXT NOT NULL DEFAULT '', ");
    sql.append(line + entryAppends);
}
if (cin.bad()) {
    // IO error
} else if (!cin.eof()) {
    // format error (not possible with getline but possible with operator>>)
} else {
    // format error (not possible with getline but possible with operator>>)
    // or end of file (can't make the difference)
}

MetaEntries.close();
[...]

It is also convention to use lower case for variable names, upper case for classes, structs and enums, and all capital letters for constants.

FalcoGer
  • 1,790
  • 5
  • 25