Delete line (textBox) from file C++ - c++-cli

I enter text into textBox, and when button is clicked how can I delete line(entered in textBox) from file?
My deleting method code:
public: System::Void deleteOneRejuser()
{
string fileName = "mainBase/main.txt";
fstream file;
file.open(fileName, ios::in);
char buf[255];
string text;
//read all lines in file and write in 'buf'
while(file.getline(buf,255,'\n'));
//converting
text = (const char*) buf;
//convert textBox text in string
System::String^ myString = textBox2->Text;
string str = msclr::interop::marshal_as< string >( myString);
int pos = text.find(str);
if ( pos == (int) string::npos )
this->label2->Text = "Bad line, not found";
text.erase( pos, str.size() );
file.close();
file.open(fileName, ios::out);
file << text;
file.close();
}
VS 2010
Windows Forms

Your reading loop will read all lines, but will discard all but the last line:
//read all lines in file and write in 'buf'
while(file.getline(buf,255,'\n'));
This is because the getline call just overwrites the contents in buf, it does not append.
Instead do something like
//read all lines in file and append to 'text'
while(file.getline(buf,255,'\n'))
text += buf;

Related

How can I read \x1a from a file? [duplicate]

I am attempting to write a bittorrent client. In order to parse the file etc. I need to read a torrent file into memory. I have noticed that fread is not reading the entire file into my buffer. After further investigation it appears that whenever the symbol shown below is encountered in the file, fread stops reading the file. Calling the feof function on the FILE* pointer returns 16 indicating that the end of file has been reached. This occurs no matter where the symbol is placed. Can somebody explain why this happens and any solutions that may work.
The symbol is highlighted below:
Here is the code that does the read operation:
char *read_file(const char *file, long long *len){
struct stat st;
char *ret = NULL;
FILE *fp;
//store the size/length of the file
if(stat(file, &st)){
return ret;
}
*len = st.st_size;
//open a stream to the specified file
fp = fopen(file, "r");
if(!fp){
return ret;
}
//allocate space in the buffer for the file
ret = (char*)malloc(*len);
if(!ret){
return NULL;
}
//Break down the call to fread into smaller chunks
//to account for a known bug which causes fread to
//behave strangely with large files
//Read the file into the buffer
//fread(ret, 1, *len, fp);
if(*len > 10000){
char *retTemp = NULL;
retTemp = ret;
int remaining = *len;
int read = 0, error = 0;
while(remaining > 1000){
read = fread(retTemp, 1, 1000, fp);
if(read < 1000){
error = feof(fp);
if(error != 0){
printf("Error: %d\n", error);
}
}
retTemp += 1000;
remaining -= 1000;
}
fread(retTemp, 1, remaining, fp);
} else {
fread(ret, 1, *len, fp);
}
//cleanup by closing the file stream
fclose(fp);
return ret;
}
Thank you for your time :)
Your question is oddly relevant as I recently ran into this problem in an application here at work last week!
The ASCII value of this character is decimal 26 (0x1A, \SUB, SUBSTITUTE). This is used to represent the CTRL+Z key sequence or an End-of-File marker.
Change your fopen mode ("In [Text] mode, CTRL+Z is interpreted as an end-of-file character on input.") to get around this on Windows:
fp = fopen(file, "rb"); /* b for 'binary', disables Text-mode translations */
You should open the file in binary mode. Some platforms, in text (default) mode, interpret some bytes as being physical end of file markers.
You're opening the file in text rather than raw/binary mode - the arrow is ASCII for EOF. Specify "rb" rather than just "r" for your fopen call.

Saving randomly generated passwords to a text file in order to display them later

I'm currently in a traineeship and I currently have to softwares I'm working on. The most important was requested yesterday and I'm stucked on the failure of its main feature: saving passwords.
The application is developped in C++\CLR using Visual Studio 2013 (Couldn't install MFC libraries somehow, installation kept failing and crashing even after multiple reboots.) and aims to generate a password from a seed provided by the user. The generated password will be save onto a .txt file. If the seed has already been used then the previously generated password will show up.
Unfortunately I can't save the password and seed to the file, though I can write the seed if I don't get to the end of the document. I went for the "if line is empty then write this to the document" but it doesn't work and I can't find out why. However I can read the passwords without any problem.
Here's the interresting part of the source:
int seed;
char genRandom() {
static const char letters[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(letters) - 1;
return letters[rand() % stringLength];
}
System::Void OK_Click(System::Object^ sender, System::EventArgs^ e) {
fstream passwords;
if (!(passwords.is_open())) {
passwords.open("passwords.txt", ios::in | ios::out);
}
string gen = msclr::interop::marshal_as<std::string>(GENERATOR->Text), line, genf = gen;
bool empty_line_found = false;
while (empty_line_found == false) {
getline(passwords, line);
if (gen == line) {
getline(passwords, line);
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(line);
break;
}
if (line.empty()) {
for (unsigned int i = 0; i < gen.length(); i++) {
seed += gen[i];
}
srand(seed);
string pass;
for (int i = 0; i < 10; ++i) {
pass += genRandom();
}
passwords << pass << endl << gen << "";
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(pass);
empty_line_found = true;
}
}
}
I've also tried replacing ios::in by ios::app and it doesn't work. And yes I have included fstream, iostream, etc.
Thanks in advance!
[EDIT]
Just solved this problem. Thanks Rook for putting me on the right way. It feels like a silly way to do it, but I've closed the file and re-openned it using ios::app to write at the end of it. I also solved a stupid mistake resulting in writing the password before the seed and not inserting a final line so the main loop can still work. Here's the code in case someone ends up with the same problem:
int seed;
char genRandom() {
static const char letters[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(letters) - 1;
return letters[rand() % stringLength];
}
System::Void OK_Click(System::Object^ sender, System::EventArgs^ e) {
fstream passwords;
if (!(passwords.is_open())) {
passwords.open("passwords.txt", ios::in | ios::out);
}
string gen = msclr::interop::marshal_as<std::string>(GENERATOR->Text), line, genf = gen;
bool empty_line_found = false;
while (empty_line_found == false) {
getline(passwords, line);
if (gen == line) {
getline(passwords, line);
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(line);
break;
}
if (line.empty()) {
passwords.close();
passwords.open("passwords.txt", ios::app);
for (unsigned int i = 0; i < gen.length(); i++) {
seed += gen[i];
}
srand(seed);
string pass;
for (int i = 0; i < 10; ++i) {
pass += genRandom();
}
passwords << gen << endl << pass << endl << "";
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(pass);
empty_line_found = true;
}
}
passwords.close();
}
So, here's an interesting thing:
passwords << pass << endl << gen << "";
You're not ending that with a newline. This means the very end of your file could be missing a newline too. This has an interesting effect when you do this on the final line:
getline(passwords, line);
getline will read until it sees a line ending, or an EOF. If there's no newline, it'll hit that EOF and then set the EOF bit on the stream. That means the next time you try to do this:
passwords << pass << endl << gen << "";
the stream will refuse to write anything, because it is in an eof state. There are various things you can do here, but the simplest would be to do passwords.clear() to remove any error flags like eof. I'd be very cautious about accidentally clearing genuine error flags though; read the docs for fstream carefully.
I also reiterate my comment about C++/CLR being a glue language, and not a great language for general purpose development, which would be best done using C++ or a .net language, such as C#. If you're absolutely wedded to C++/CLR for some reason, you may as well make use of the extensive .net library so you don't have to pointlessly martial managed types back and forth. See System::IO::FileStream for example.

Get FileName out of SaveDialog and change it dynamically c++

here is my problem:
I want to expand the FileName that the user gives the program in the SaveFileDialog with an index number.
I get the complete Path out of the dialog and search '.' in it.
System::String^ str = saveFileDialog1->FileName;
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
size_t convertedChars = 0;
size_t sizeInBytes = ((str->Length + 1) * 2);
errno_t err = 0;
char *FileName = (char*)malloc(sizeInBytes);
err = wcstombs_s(&convertedChars,
FileName, sizeInBytes,
wch, sizeInBytes);
for (size_t i = 0; i < sizeof((*FileName )); i++)
{
if (FileName [i]=='.')
{
}
}
and at this point I have tried different things to edit the FileName with:
insert(i-1, ("_%i",i));
Nothing I have tried, works how I want it.
I want to save different pictures of a camera and with this index it is easier for the user to find the picture he want.
Thanks in advance!
Knut
So, you basically need to split filename to its raw name and extension, and then join these parts with some index. You can use this function:
string get_indexed_name(string filename, string index)
{
size_t lastindex = filename.find_last_of("."); // get position of dot
string rawname = filename.substr(0, lastindex); // get string contents before dot
string extension = filename.substr(lastindex + 1); // get string contents after dot
return rawname + index + "." + extension; // return indexed name
}
This way uses predefined standard functions. If you want to do (and learn) it yourself, try to implement functions find_last_of and substr. Then you can use your own implementation.
If there is some compilation problem, be sure to start your source code with these lines:
#include <iostream>
using namespace std;
Here is my Solution:
System::String^ str = saveFileDialog1->FileName;
std::string sFilePath = msclr::interop::marshal_as< std::string >(str);
std::string fileExtension=msclr::interop::marshal_as< std::string >(str);
size_t pos= sFilePath.find('.', 1);
sFilePath = sFilePath.substr(0, pos );
fileExtension = fileExtension.substr(pos);
for(size_t i=0; i<100; i++){
std::string fileName;
fileName = sFilePath + std::to_string(i) + fileExtension;}
For this solution you have to include.
#include <msclr\marshal_cppstd.h>
And if you want that your file number is with leaded zeros you have to use
stringstream like this:
string fileName;
string fileNumber ;
stringstream ss;
ss <<'_'<< setfill('0') << setw(4) << std::to_string(i);
fileNumber = ss.str();
fileName = f_sFilePath + fileNumber + f_sFileExtension;

How to writefile in new line in WIN32 API

I'm trying to write data to file. However, I want to add new data in new line, but now I can't.
HANDLE hFile;
hFile = CreateFile(_T("HELLO.txt"), // file to open
GENERIC_WRITE, // open for writing
0, // share for writing
NULL, // default security
// CREATE_NEW, // existing file only
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
// Write to File
BOOL bErrorFlag = FALSE;
DWORD dwPtr = SetFilePointer( hFile, 0, NULL, FILE_END); //set pointer position to end file
LPWSTR data = _T("Data '\n'");
DWORD dwBytesToWrite = lstrlenW(data)*2;
DWORD a = 0;
bErrorFlag = WriteFile(
hFile, // open file handle
data, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwPtr, // number of bytes that were written
NULL); // no overlapped structure
Windows uses a CR/LF combination to signify the end of line, you need to write "\r\n" if you want the line break to show up correctly in, e.g., Notepad.

Objective C use char string in system()

so i have this code
char processName[50] = {0}; // init all to 0
printf("Enter the process to kill: ");
scanf("%s", processName); // read and format into the str buffer
printf("Attempting to kill %s\n", processName); // print buffer
system("killall %s", processName);
put this causes the error "too many arguments to function 'system'"
The function system takes a single argument, the command to execute. You will have to create a temporary string to build such command.
char command[1024] = {};
sprintf(command, "killall %s", processName);
system(command);