Modify user input to open a file

I'm trying to make a program that will accept a string input then use the vector function .pushback() to add characters into the string so I can open a file.

Basically the program should

*Ask for a characters Name
*Convert the characters name into the format of the games log file
*Open the log file

For some reason I'm getting these errors here

error: conversion from 'const char [8]' to non-scalar type 'std::vector<std::basic_string<char> >' requested

error: invalid user-defined conversion from 'char' to 'const value_type& {aka const std::basic_string<char>&}' [-fpermissive]


Here is the code!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <vector>

int main()
{
  std::string character_name;
  std::vector<char>file_name = "gamelog_";
  int cname_length;

  std::cout << "Please enter the name of the character log to parse: ";
  std::cin >> character_name;
  cname_length = character_name.length();

  for (int i = 0; i < cname_length; i++){
    file_name.push_back(character_name[i]);//add character name to file_name vector
  }

  //add .txt to end of file_name vector
  file_name.push_back('.');
  file_name.push_back('t');
  file_name.push_back('x');
  file_name.push_back('t');

  std::ifstream file_in;
  file_in.open(file_name.c_str()); // open the game log file
  if (!file_in.good()){
  std::cout << "Log File Not Found\n";
  return 1;
  } // exit if file not found

  return 0;
}
Last edited on
closed account (G30GNwbp)
Assuming that you have a good reason for wanting to use vectors; here is asmall example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <algorithm>
#include <vector>

int main () {
  std::string t_file_name {"gamelog_"};
  std::vector<char> file_name(t_file_name.size ());

  std::copy ( t_file_name.begin (), t_file_name.end (), file_name.begin() );

  file_name.push_back('.');
  file_name.push_back('t');
  file_name.push_back('x');
  file_name.push_back('t');

  std::cout << "file_name contains: ";
  for (auto i : file_name)
    std::cout << i;
  std::cout << '\n';

  t_file_name.resize( file_name.size ());
  std::copy ( file_name.begin (), file_name.end (), t_file_name.begin() );
  std::cout << t_file_name.c_str() << '\n';

  return 0;
}

Last edited on
I don't really have a good reason to be using a vector when I think about it.

I thought it might be quicker to create a simple program using vectors but I think it would ultimately make a program run slower using a vector like this.

Vectors seem to be slower than fixed length arrays for some reason.

I thought having an undefined "array" size through a vector would make it easier to manipulate data.

I suppose I could just use a fixed length character array with 64 bits because I doubt any character name would ever reach close to that size.

Then I should figure out a way to delete the array when I'm done with it to free up the memory. I'll try to write something like that and post the result after I grab something to eat. I can't think straight when hungry.

That code above wouldn't compile for me. I added in the #include <string>

and changed the line std::string t_file_name {"gamelog_"};

to std::string t_file_name = "gamelog_"; and it still wouldn't compile. I'll see if I can figure out what you were trying after a snack also ;p
Last edited on
Why not just use strings and the append method for strings??
I got this to work after taking a break and eating something.

Not sure if this is a great way to do it, but please let me know what you think!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <fstream>
#include <string>

int main()
{
  std::string character_name;
  std::string file_name_prefix = "gamelog_";
  std::string file_name_suffix = ".txt";
  char file_name[64];
  int cname_length;

  //populate file_name array with null characters
  for (int i = 0; i < 64; i++){
    file_name[i] = '\0';
  }

  //set up first part of file_name array
  for (int i = 0; i < 8; i++){
    file_name[i] = file_name_prefix[i];
  }

  std::cout << "Please enter the name of the character log to parse: ";
  std::cin >> character_name;

  cname_length = character_name.length();
  //add the character name to the file_name array
  for (int i = 8; i < (cname_length + 8); i++){
    file_name[i] = character_name[i-8];
  }
  //add the .txt to the file_name array
  for (int i = (cname_length + 8); i < (cname_length + 12); i++){
    file_name[i] = file_name_suffix[i - (cname_length + 8)];
  }

  //print out the file_name array
  for (int i = 0; file_name[i] != '\0'; i++){
    std::cout << file_name[i];
  }

  std::ifstream file_in; // create a file-reading object
  file_in.open(file_name); // open the file
    if (!file_in.good())
        return 1; // exit if file not found

  return 0;
}
closed account (G30GNwbp)
Garion wrote:
That code above wouldn't compile for me.


It's C++11 try this:

g++ -std=c++11 -Wall -Wextra -otemp temp.cpp
the C++ class has a handy c_str() function that returns... a c-style string. You'd be better off leveraging the C++ string append functions (the string class operator+ does the exact same thing as well) and just call the c_str() function to open your file.

1
2
3
4
5
6
// Append all your strings together to create your filename string
std::string filename = file_name_prefix + character_name + file_name_suffix;

...
// Open the file
file_in.open(filename.c_str());
I should read about that more. I've only read the tutorials on this website so far but I think I'm not setting up arrays to be c++ 11 compliant.

Would Line 54 below work to free up the memory that the file_name array used?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <fstream>
#include <string>

int main()
{
  std::string character_name;
  std::string file_name_prefix = "gamelog_";
  std::string file_name_suffix = ".txt";
  std::ifstream file_in; // create a file-reading object
  char file_name[64];
  int cname_length;

  do {
    //populate file_name array with null characters
    for (int i = 0; i < 64; i++){
        file_name[i] = '\0';
    }

    //set up first part of file_name array
    for (int i = 0; i < 8; i++){
        file_name[i] = file_name_prefix[i];
    }

    std::cout << "Enter the name of the character log to parse,\nor type \"exit\" to end the program:\nCharacter Name: ";
    std::cin >> character_name;

    if (character_name == "exit"){
            std::cout << "Program ended";
            return 1;
            }

    cname_length = character_name.length();
    //add the character name to the file_name array
    for (int i = 8; i < (cname_length + 8); i++){
        file_name[i] = character_name[i-8];
    }
    //add the .txt to the file_name array
    for (int i = (cname_length + 8); i < (cname_length + 12); i++){
        file_name[i] = file_name_suffix[i - (cname_length + 8)];
    }

    file_in.open(file_name); // open the file
    if (!file_in.good()){
            std::cout << "\n" << character_name << "'s Log file was not found.\n";
            }
  } while (!file_in.good());//while loop bracket

  //print out the file_name array
  for (int i = 0; file_name[i] != '\0'; i++){
        std::cout << file_name[i];
        }
  std::cout << " was successfully opened";
  delete [] file_name;//Would This work here to free up the memory?
  return 0;
}//main bracket 


Somebody told me before that the way to set up a c++ 11 compliant array was

char * file_name = new char[64]

I'm just unsure how to move a strings data into an array declared in that fashion.
Where would i put this:

g++ -std=c++11 -Wall -Wextra -otemp temp.cpp

in the code you wrote to make it compile.

Also, how would I make sure I'm using c++ 11?

I've been using codeblocks 12.1 but I don't know which version of c++ it uses to be honest.
Last edited on
Any C++ array is C++11 compliant. There are some new things that you can do for array declaration, etc. in C++11 but there's no change in the way arrays are initialized. The line:

char * file_name = new char[64]

Is the same for all versions of C++/C.

this is a command-line instruction.
g++ -std=c++11 -Wall -Wextra -otemp temp.cpp


I've never used Code::blocks, but I assume you press some button or key and your code gets compiled. The compiler you use is dependent on the operating system you are on. If you are on Linux, you're probably using GCC, which is invoked on the Linux command line with g++.

Also, how would I make sure I'm using c++ 11?

You'll have to look at your compiler version, and whether or not you have those options enabled. Again, I don't know how to configure your Code::blocks settings, but I'm sure you can go in there and see your compiler version and configure compiler flags to support the standard.
Last edited on
closed account (G30GNwbp)
A google query informs me that the way to set compiler flags for code blocks is:

Project -> Build Options -> Compiler Flags


You should familiarize yourself with your IDE enough to know:

1.) what compiler you are using
2.) what warning you have set (warning really help)
Last edited on
Thank you. I wasn't sure what that line of information actually meant/was asking me to do.

I was able to find most of those compiler settings and get the above code to compile.

I will mess with it some more to learn what I can.

I will have to figure out when the settings are required but I'm sure that will come with more experience and just making code.

I'm going to mark this as solved because I have two working examples now.
Last edited on
Topic archived. No new replies allowed.