C++ the dynamic array and file reading don't work together - c++

Such a code:
int _tmain(int argc, _TCHAR* argv[])
{
int *test = new int[];
ifstream f("ofile.txt");
for (int i=0,v; i<10; i++)
{
f>>v;
test[i]=1;
cout<<"\nv = "<<v<<", i = "<<i<<endl;
}
return 0;
}
caused of this message after compiling:
I guess (correct me if I'm wrong) here is some error about memory, but details are unknown for me. If I remove one of them (file reading or array) it works.
So it will be great to hear an explanation of the problem.

You're thinking java. To allocate an array like that you need to give a size.
e.g.
int *test = new int[20];
However a better scheme would be to use a vector of integers.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm> // for sort()
int main(int argc, char *argv[])
{
std::vector<int> data;
std::ifstream fsin("ofile.txt");
int count = 0;
while (fsin.good())
{
int v;
fsin >> v;
if (fsin.good())
{
data.push_back(v);
std::cout << "\nv = " << v << ", i = " << count++ << std::endl;
}
}
std::sort(data.begin(), data.end());
for (size_t i=0; i<data.size(); i++)
std::cout << i << '\t' << data[i] << std::endl;
return 0;
}

You have to allocate a fixed size array, int *test = new int[]; shouldn't even work.
If the size is known, use int *test = new int[size];, otherwise try using a std::vector or std:array.

Related

C++ delete[] array; [duplicate]

This question already has answers here:
C++ after delete pointer
(4 answers)
Closed 6 months ago.
#include <iostream>
#include <string>
using namespace std;
void print(string data[], int size) {
cout << "Print array" << endl;
for (int i=0; i<size; i++) {
cout << data[i] << ", ";
}
cout << endl;
}
int main(int argc, char** argv) {
string arr1[] = {"Apple", "Banana", "Coconut", "Durian"};
string *arr2 = new string[6];
arr2[4] = "Eggplant";
arr2[5] = "AppleBanana";
std::copy(std::begin(arr1), std::end(arr1), arr2);
print(arr2, 6);
delete[] arr2;
print(arr2, 6);
return 0;
}
I was wondering why delete[] arr2; only free up the arr2[0] because after I print it again only the first element in arr2 is freed but the rest still got the elements
I don't quite understand the free()/delete yet so it would be nice if someone also help explain it. I have been asking professor about it and I'm still confused as to why freeing up arr2 still got elements in its
Maybe, it is better to delete array in this way
for(int i = 0; i < size; i++)
{
delete [] arr2[i];
arr2[i] = nullptr;
}
Also you are not allowed to use the deleted arr2 after you used the keyword delete because it will cause some problems in time of and after compilation

Dynamically allocate an array from a textfile and retain its values

After looking at some other similar questions, this is what I've written so far:
#include <iostream>
#include <fstream>
#include <string>
void read_from_file() {
int* arr;
int length;
std::string file_name = "data.txt";
std::ifstream file_data;
file_data.open(file_name.c_str());
if (file_data.is_open())
{
file_data >> length;
arr = new int[length];
for (int i = 0; i < length; i++)
{
file_data >> arr[i];
std::cout << arr[i] << " ";
}
file_data.close();
}
else
std::cerr << "Cannot open the file " << file_name << std::endl;
}
All good here, until I try to manipulate the array's values. For example, I have to check if the array is sorted in ascending order. I don't know how to get back where I read the array and get the values.
bool check_if_sort_asc(int* arr, int length)
{
for (int i = 0; i < length - 1; i++)
if (arr[i] > vect1[i + 1])
return false;
return true;
}
int main()
{
int *arr;
int length;
read_from_file();
if (check_if_sort_asc(arr, length)==true)
std::cout << " The array is sorted in ascending order ";
else
std::cout << "The array is not sorted in ascending order ";
return 0;
}
The immediate fix is this
Change read_from_file to return the data it read
int * read_from_file() {
int *arr = NULL;
then return arr at the end of it
else
std::cerr << "Cannot open the file " << file_name << std::endl;
return arr;
}
and finally use the returned value in main
arr = read_from_file();
and free it when you have finished
delete [] arr;
But your code doesnt compile, because of that vect1 stuff, plus you should use std::vector.
As Bob_ points out you need the length too, so either
use std::vector
make the arr array one bigger and place the length as first entry
use std::vector
pass a length int by reference into read_form_file (see below)
use std::vector
ie
int * read_from_file(int * length) {
int *arr = NULL;
...
file_data >> *length;
But mainly, use std::vector

How do I read a stringstream into a char *[40] / char ** array?

I am working on creating a UNIX shell for a lab assignment. Part of this involves storing a history of the past 10 commands, including the arguments passed. I'm storing each command as a C++ string, but the parts of the program that actually matter, and that I had no input in designing (such as execve) use char * and char ** arrays exclusively.
I can get the whole command from history, and then read the program to be invoked quite easily, but I'm having a hard time reading into an arguments array, which is a char *[40] array.
Below is the code for a program I wrote to simulate this behavior on a test string:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char *chars[40];
string test = "Hi how are you";
stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
string test_2;
testStream >> test_2;
if (testStream.fail())
{
break;
};
chars[i] = (char *)test_2.c_str();
i++;
}
for (int i=0; i < 4; i++)
{
cout << chars[i];
}
cout << "\n";
}
I get the feeling it has something to do with the array being declared as an array of pointers, rather than a multi-dimensional array. Am I correct?
This line:
chars[i] = (char *)test_2.c_str();
leaves chars[i] 'dangling' when you go back round the loop or fall off the end. This is because test_2.c_str() is only valid while test_2 is in scope.
You'd do better to do something like this:
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector <std::string> args;
std::string test = "Hi how are you";
std::stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
std::string test_2;
testStream >> test_2;
if (testStream.fail())
break;
args.push_back (test_2);
i++;
}
auto char_args = std::make_unique <const char * []> (i);
for (int j = 0; j < i; ++j)
char_args [j] = args [j].c_str ();
for (int j = 0; j < i; ++j)
std::cout << char_args [j] << "\n";
}
Now your vector of strings remains in scope while you are building and using char_args.
Live demo

Passing array as argument to std::thread

I'm having difficulty passing an array of integers to a function using std::thread. It seems like thread doesn't like the array portion of it. What other way is there to pass an array to a threaded function?
#include <thread>
#include <ostream>
using namespace std;
void process(int start_holder[], int size){
for (int t = 0; t < size; t++){
cout << start_holder[t] << "\n";
}
}
int main (int argc, char *argv[]){
int size = 5;
int holder_list[size] = { 16, 2, 77, 40, 12071};
std::thread run_thread(process,holder_list,size);
//std::ref(list) doesnt work either
//nor does converting the list to std::string then passing by std::ref
run_thread.join();
}
Since you are using C++ start using std::vector or std::list instead of the c-style arrays. There are many other container types as well. If you want a fixed size array use std::array instead (since C++11).
These containers have functions to get the size so you do not need to send it through as a separate argument.
#include <thread>
#include <iostream>
#include <vector>
void process(std::vector<int> start_holder){
for(int t = 0; t < start_holder.size(); t++){
std::cout << start_holder[t] << "\n";
}
// Or the range based for
for(int t: start_holder) {
std::cout << t << "\n";
}
}
int main (int argc, char *argv[]){
std::vector<int> holder_list{ 16, 2, 77, 40, 12071};
std::thread run_thread(process, holder_list);
run_thread.join();
}
Make size constant:
#include <thread>
#include <iostream>
void process(int* start_holder, int size){
for (int t = 0; t < size; t++){
std::cout << start_holder[t] << "\n";
}
}
int main (int argc, char *argv[]){
static const int size = 5;
int holder_list[size] = { 16, 2, 77, 40, 12071};
std::thread run_thread(process, holder_list, size);
run_thread.join();
}
If size is variable, int arr[size] is not a standard C++. It is a variable array extension to the language as your compiler says in the error and is not compatible with int* aka int [].

(C++) Trying to remember where to define functions

It's be awhile since I touched C++, but I'm writing inside my main I have a function called "solution" and right now that line is giving me the error: "a function definition is not allowed here before '{'"
Afterwards I thought I was supposed to write my funciton definitions after my main(), but that led to another slue of errors.
Also, as my code stands, I get the error of "invalid arguments" when I call my function solution and pass it to my outfile.
I also get the error on the final '{' of "expected '{' at end of input."
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(int argc, char** argv) {
ifstream infile("TEST.txt", std::ifstream::in);
string line;
vector<string> inputLines;
if(infile.is_open()){
while(getline(infile, line)){
cout << line << '\n';
inputLines.push_back(line);
}
}
infile.close();
ofstream outfile("output.txt", std::ofstream::out);
for(unsigned int i = 1; i < inputLines.size(); i+= 3){
int credit = inputLines[i];
int numofItems = inputLines[i+1];
int numofItemscopy = inputLines[i+1];
vector<int> items;
stringstream ssin(inputLines[i+2]);
int x = 0;
while(ssin.good() && x < numofItems){
ssin >> items[x];
++x;
}
outfile << solution(credit,
numofItems,
numofItemscopy,
items.size());
outfile << inputLines[i] << '\n';
}
outfile.close();
return 0;
}
string solution(int cred, vector<int> original, vector<int> copy, int size){
for(int i = 0; i < size; i++ ){
for (int ii = 0; ii < size; ii++){
if(original[i] + copy[ii] == cred){
return std::string(i) + std::string(ii);
}
}
}
return "";
}
EDIT:
I put my solution function after my main, now I am getting the following errors:
On all three lines of :
int credit = inputLines[i];
int numofItems = inputLines[i+1];
int numofItemscopy = inputLines[i+1];
I get the error: "cannot convert ‘std::basic_string’ to ‘int’ initialization"
Also when I call my "solution" function:
outfile << solution(credit,
numofItems,
numofItemscopy,
items.size());
I get the error that "Solution was not declared in this scope."
First of all, you need to declare your function before you use it in your main function. You can then define it after your main function if you so desire. The compiler goes from top to bottom, and it only knows about what it has seen up to that point. The compiler has not yet seen the solution function when you call it in main, so it does not know what to do.
string solution(int cred, vector<int> original, vector<int> copy, int size);
Your declaration should look like this. To declare a function you just take its header and instead of giving it a body with {}, you just end the line with a ; like follows.
int num = stoi("32");
As for parsing strings to integers, in C++11 you can do that simply as seen above. See more info on that here: https://stackoverflow.com/a/11354496/2749485
See below for how your code should now look:
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
string solution(int cred, vector<int> original, vector<int> copy, int size);
int main(int argc, char** argv) {
ifstream infile("TEST.txt", std::ifstream::in);
string line;
vector<string> inputLines;
if(infile.is_open()){
while(getline(infile, line)){
cout << line << '\n';
inputLines.push_back(line);
}
}
infile.close();
ofstream outfile("output.txt", std::ofstream::out);
for(unsigned int i = 1; i < inputLines.size(); i+= 3){
int credit = stoi(inputLines[i]);
int numofItems = stoi(inputLines[i+1]);
int numofItemscopy = stoi(inputLines[i+1]);
vector<int> items;
stringstream ssin(inputLines[i+2]);
int x = 0;
while(ssin.good() && x < numofItems){
ssin >> items[x];
++x;
}
outfile << solution(credit,
numofItems,
numofItemscopy,
items.size());
outfile << inputLines[i] << '\n';
}
outfile.close();
return 0;
}
string solution(int cred, vector<int> original, vector<int> copy, int size){
for(int i = 0; i < size; i++ ){
for (int ii = 0; ii < size; ii++){
if(original[i] + copy[ii] == cred){
return std::string(i) + std::string(ii);
}
}
}
return "";
}
Function definitions should go before your main() if you want to have them in the same source file