How do i choose where i output in a csv file - c++

I know the title is a bit confusing, so i will try my best to explain it here.
When outputting to an excel file you can move the output location down by outputting a "\n" or by using std::endl;
is there something similar to move up?
to make it easier to understand i have some code:
std::ofstream outFile;
outFile.open( "outfile.csv" );
outFile << "test \n";
outFile << "test2" << "," << "test3";
in this case the "test" text is found ( in the excel file ) at A1, the test2 is found at A2, after that i can move it right, test3 is located at B2.
the question is: is there a way to move the next output up and left ( in this case, how can i move the next output to e.g. A1 )
a way to reset the position would work too.

Moving the position in a file is possible, but it won't help you much, because your entries are all of different length. Text files are just a bunch of characters, there is no A1 or B2 in the text file.
Instead of working on the text file directly, if feasible, you should load all the contents into a data structure that allows you to modify specifc entries given an index.
You could use a 2d array or a std::map<char,std::vector<std::string>> data, so you can access an element at A1 via data['A'][1].

Related

why I cant read a file to an integer vector?

well! I have a text file including some integer values and non-integers like character strings and white spaces so I want only to read integers values so I used a vector of integers but when I read the file the opining is ok but it seems the first input fails thus breaks the loop!!!
here is my main example:
ifstream in("file.txt");
if(in.fail())
cout << "opening failed!" << endl;
//opening is fine!
int value;
vector<int> v;
while(in >> value) // the problem here; it fails why?
{
cout << "ok"; // not printed
v.push_back(value);
}
cout << v.size() << endl; // 0??!!
this is the content of file.txt:
32 43 24 32
15 23
57
77 81
if I make a vector of chars it's ok but I want only to use one of integers
*** I already used a code like this and worked fine but now I don't know what happened??!!! it's really annoting
any help, comment, tip is welcome and appreciated
This line:
while(in >> value)
says while I can read integers...
But in the post this may not be true - you are not handling this case.
Either read stuff that is not integers and handle it. Or just read strings and then decide what to do.
In addition
cout << "ok"; // not printed
is because it is buffered.
Do this
cout << "ok" << flush; // printed
excuse me first for annoying you with nonsense question. finally I managed to discover the error:
in my main folder of project I unintentionally created a winrar file input.rar then I didn't remove it but rename it to input.txt it's ok I opened it manually and removed some unreadable characters. then I put inside it the content above of integers then my c++ application succeeds in opening it but can't read it.
*now I removed it input.txt which was input.rar and created a new document text input.txt and now everything is good!!!
thank you for your collaboration. and this post may help someone else.
* don't create rar file or other formats then rename them to be text files and try to read them via your c++ fstream because it'll fail in fact it'll produce an error-prone which looks impossible to solve

fprintf always write to the end of the file even when I do rewind(fileptr) before, c++

I want to append a file and update some of its lines at the same time.
After appending as I desired, say I want to change only the first line, here is what I tried:
outputptr = fopen(outputName.c_str(), "ar+b");
cout << ftell(outputptr) << " ";
rewind(outputptr);
cout << ftell(outputptr) << "\n";
fprintf(outputptr, "abc");
But that code do not replace the first three letters with abc, instead it also appends the file and writes abc to the end. cout were 60 and 0 for this case, so pointer in fact is moved to the beginning.
How do I go any line of a given file and modify only that line?
The definition of 'a' in the mode field says:
(I've cut out the bits that are relevent for this question - it says some other stuff too)
... Repositioning operations (fseek, fsetpos, rewind) affects the next
input operations, but output operations move the position back to the
end of file. ...
You probably want "r+b".
http://www.cplusplus.com/reference/cstdio/fopen/

How to read from a text file and split sentences apart in C

I want to read a series of questions from a text file. Each question is separated by a comma, so I am thinking that I have to check for each character to not be equal to a comma before copying the character?
The text file looks something like this "Is it red?, Is it bigger than a mailbox?, Is it an animal?"
In case it affects the code, I want to copy each string into a node to put in a tree later on.
while (fgets(stringPtr, 100, filePtr) != ',')
strcpy(stringPtr, treeNode);
Is something like this ok?
Given your description - something like the follow:
std::string question_string;
std::set<std::string> my_tree;
if (std::ifstream file_stream{filename})
{
while (std::getline(file_stream, question_string, ','))
my_tree.insert(question_string);
}
else
std::cerr << "unable to open " << filename << '\n';
You'll need to get the filename from somewhere, include the relevant headers (google the classes if you need to).

How to store 3D matrix in text file so that it can be imported to Matlab?

I have a text file as an output of a c++ program. Its actually a 3x100x200 element matrix. 3x100 2d matrices over 200 timestamps. I want to store this such that I can load it in Matlab workspace and then visualize it in a 3d plot. I am not able to figure out the structure of the text file. As in where should I put a "[..]" and where ";" and where a " " or ",".
Could someone please give an example so that I can print out in the file from the c++ code in a that manner
Forget the text file. Instead, write a .mat file using the Matio library. This way you will be able to quickly add some more data fields in case you need to.
If you really want to use a text file, you can first write the matrix dimensions, then all the elements, and finally do some reshaping as suggested here.
I found a hack without using any extra libs.
I just output every 2d matrix as outMat(:,:,matIndex) and incremented matIndex in a loop. And then I ran the .m in matlab as a script.
void printArrs(){
int i;
// B(:,:,1) = [1 2 3; 4 5 6];
// B(:,:,2) = [7 8 9; 0 0 0];
ofstream outFile;
outFile.open ("forPlot.m", ios::out | ios::app);
matIndex++;
outFile << "outMat(:,:," << matIndex << ") = [";
for(i=0;i<fftLen;i++){
outFile << Mag[0][i] << " ";
outFile << Mag[1][i] << " ";
outFile << Mag[2][i] << ";" << endl;
}
outFile << "];" << endl;
outFile.close();
}
Thanks everyone for your answers.
For some answers I wasnt clear enough I guess, because they assumed I want to write 'from' Matlab and not 'to' Matlab while it was the other way.
Try googling ".csv" to find out what a comma separated variable file is. That should help, you can import them into Matlab if I recall correctly.
If you really want to use text files, although I suggest you go for the earlier mentioned Matio library, you can save a 3D array by reshaping it to 2D to write, and by reshaping it to 3d after you read. Have a look at this simple MATLAB code. It writes a 3D matrix to a csv file. After writing, the csv file contains a 2D matrix with the second and third dimensions streamed as a vector:
A = rand(3,10,10);
csvwrite('data.txt', A);
B = csvread('data.txt');
% B is now 3 x 100 matrix, so you need to reshape
B = reshape(B, 3, 10, 10);
Better to save it to a .mat file. You won't have to bother with the file structure this way.
See the documentation of the save function. Edit: I misread the question and didn't realize you're trying to save the matrix in C++. I suggest you follow Pukku's advice and use the Matio library.
To load a .mat file in Matlab, just use
load('myfile.mat')
Which will put the matrix in your workspace.

How do I go back to end of the first line in csv file?

I am using ofstream to write a csv file.
Currently, I am writing it left to right using "<<" operator, which is easy.
For example,
Shape,Area,Min,Max
Square,10,2,11
Rectangle,20,3,12
I want to change so that it looks like
Shape,Square,Rectangle
Area,10,20
Min,2,3
Max,11,12
I know I can use "<<" operator and just write it that way, but I am using some loops and it's not possible to use "<<" operator write it like that.
So I am looking for a way to write in the order, for example
Shape,
Area,
Min,
Max,
Then becomes
Shape,Square
Area,10
Min,2
Max,1
So It's basically going from top to bottom rather than left to right.
How do I use ofstream to code this? I am guessing I have to use seekp, but I'm not sure how.
Thank you very much.
You can't insert other than at the end of an ostream without
overwriting already written data. For something like what
you're trying to do, you probably have to collect each row in
separate string (perhaps using ostringstream to write it), then
output the rows. Something like:
std::ostringstream label;
label << "Shape";
std::ostringstream area;
area << "Area";
std::ostringstream min;
min << "Min";
std::ostringstream max;
max << "Max";
for (std::vector<Shape>::const_iterator> it = shapes.begin();
it != shapese.end();
++ it)
{
label << ',' << it->TypeName();
area << ',' << it->Area();
min << ',' << it->min();
max << ',' << it->max();
}
dest << label.str() << '\n';
dest << area.str() << '\n';
dest << min.str() << '\n';
dest << max.str() << '\n';
You can use the old FILE* API, seeking as needed. IOStreams also allow you to seekp and seekg. But manipulating files like this will be difficult. If you write out, say, 100 bytes, seekp to the beginning and start writing more data, you're going to overwrite what's already there (it doesn't automatically get shifted around for you). You're likely going to need to read in the file's contents, manipulate them in memory, and write them to disk in one shot.
Eventhough it is inefficient, it could be done by writing fixed size lines (40 characters?) with extra spaces, so you can go to a line and (fixed) position by seeking line*40+position (or look for the comma) and overwrite the spaces.
Now that you have this knowledge, go for the approach as mentioned by Martin