Delete a part of a file? - c++

I have want to code a program that functions to open a file and if I find "Hello World", the program will automatically copy the text before "Hello World" in to a new file.
The problem is, how could I delete the text 'hello world' in the 'buffer', for example :
buffer = new char [Size];
ifstream fstr;
fstr.open(path, ios::in);
fstr.read(buffer, (Size));
fstr.close();
//what should i write here about copying the rest of the text except
//Hello World?
ofstream outputFile(path2, ios::out);
outputFile << buffer;
outputFile.close();
Thank you for helping me :) Btw I'm using Borland C++ and I'm a learner.

Assuming the file is all text you could use strstr to find "Hello World" and then set the end of the string.
char *Found = strstr(buffer, "Hello World");
if (Found != NULL)
*Found = 0;

First some gotcha! type issues.
What if the file doesn't contain "Hello World"?
What if it contains "Hello World"?
What if it contains "Hello World", but the "World" starts on the next line?
I don't have the answer to these. That's up to you, and your instructor if this is homework.
Now a suggestion: Use C++ strings (std::string) rather than C-style strings.
In C you could call strstr to find the location of that string. If found, either write a 0 at the found location, or strcpy the empty string to the found location.
In C++ you can find the location of the target string with the member function find. If found, erase the stuff at and after the found location with the member function erase.
Which function / member names makes more sense? Which method of erasing from "Hello World" on makes more sense? Which code would you rather come back to six months from now?

Related

No methods of read a file seem to work, all return nothing - C++

EDIT: Problem solved! Turns out Windows 7 wont let me read/ write to files without explicitly running as administrator. So if i run as admin it works fine, if i dont i get the weird results i explain below.
I've been trying to get a part of a larger program of mine to read a file.
Despite trying multiple methods(istream::getline, std::getline, using the >> operator etc) All of them return with either /0, blank or a random number/what ever i initialised the var with.
My first thought was that the file didn't exist or couldn't be opened, however the state flags .good, .bad and .eof all indicate no problems and the file im trying to read is certainly in the same directory as the debug .exe and contains data.
I'd most like to use istream::getline to read lines into a char array, however reading lines into a string array is possible too.
My current code looks like this:
void startup::load_settings(char filename[]) //master function for opening a file.
{
int i = 0; //count variable
int num = 0; //var containing all the lines we read.
char line[5];
ifstream settings_file (settings.inf);
if (settings_file.is_open());
{
while (settings_file.good())
{
settings_file.getline(line, 5);
cout << line;
}
}
return;
}
As said above, it compiles but just puts /0 into every element of the char array much like all the other methods i've tried.
Thanks for any help.
Firstly your code is not complete, what is settings.inf ?
Secondly most probably your reading everything fine, but the way you are printing is cumbersome
cout << line; where char line[5]; be sure that the last element of the array is \0.
You can do something like this.
line[4] = '\0' or you can manually print the values of each element in array in a loop.
Also you can try printing the character codes in hex for example. Because the values (character codes) in array might be not from the visible character range of ASCII symbols. You can do it like this for example :
cout << hex << (int)line[i]

opening output filestreams with string names

Hi I have some C++ code that uses user defined input to generate file-names for some output files:
std::string outputName = fileName;
for(int i = 0; i < 4; i++)
{
outputName.pop_back();
}
std::string outputName1 = outputName;
std::string outputName2 = outputName;
outputName.append(".fasta");
outputName1.append("_Ploid1.fasta");
outputName2.append("_Ploid2.fasta");
Where fileName could be any word the user can define with .csv after it e.g. '~/Desktop/mytest.csv'
The code chomps .csv off and makes three filenames / paths for 3 output streams.
It then creates them and attempts to open them:
std::ofstream outputFile;
outputFile.open(outputName.c_str());
std::ofstream outputFile1;
outputFile1.open(outputName1.c_str());
std::ofstream outputFile2;
outputFile2.open(outputName2.c_str());
I made sure to pass the names to open as const char* with the c_str method, however if I test my code by adding the following line:
std::cout << outputFile.is_open() << " " << outputFile1.is_open() << " " << outputFile2.is_open() << std::endl;
and compiling and setting fineName as "test.csv". I successfully compile and run, however,
Three zeros's are printed to screen showing the three filestreams for output are not in fact open. Why are they not opening? I know passing strings as filenames does not work which is why I thought conversion with c_str() would be sufficient.
Thanks,
Ben W.
Your issue is likely to be due to the path beginning with ~, which isn't expanded to /{home,Users}/${LOGNAME}.
ifstream open file C++
This answer to How to create a folder in the home directory? may be of use to you.
Unfortunately, there is no standard, portable way of finding out exactly why open() failed:
Detecting reason for failure to open an ofstream when fail() is true
I know passing strings as filenames does not work which is why I thought conversion with c_str() would be sufficient.
std::basic_ofstream::open() does accept a const std::string & (since C++11)!

Print a string with fprintf

I am having an issue with printing a string which im using for debug purposes.
I create the string like so:
//checker is int
std::stringstream buttonx;
buttonx << "Button" << checker << "_x";
Now i try to print it to my error.txt file
FILE * p;
p = fopen ("error.txt","w");
fprintf(p, "%s" , buttonx.str());
fclose(p);
The output is:
,æ0
Its different every time. I'm not sure whats going on was hopeing some could explain the mistake?
fopen is plain C and cannot handle std::string. You need to input a char*, which you can access by calling .c_str() on the string, like this:
fprintf(p, "%s", buttonx.str().c_str());
the function fprintf wants a null terminated string (a C string); you need the c_str() instead of yours:
buttonx.c_str()

How do I insert a variable result into a string in C++

I just started learning C++ in Qt and I was wondering how can I put a variables result in a string? I'm trying to use this for a simple application where someone puts their name in a text field then presses a button and it displays there name in a sentence. I know in objective-c it would be like,
NSString *name = [NSString stringWithFormatting:#"Hello, %#", [nameField stringValue]];
[nameField setStringValue:name];
How would I go about doing something like this with C++? Thanks for the help
I assume we're talking about Qt's QString class here. In this case, you can use the arg method:
int i; // current file's number
long total; // number of files to process
QString fileName; // current file's name
QString status = QString("Processing file %1 of %2: %3")
.arg(i).arg(total).arg(fileName);
See the QString documentation for more details about the many overloads of the arg method.
You don´t mention what type your string is. If you are using the standard library then it would be something along the lines of
std::string name = "Hello, " + nameField;
That works for concatenating strings, if you want to insert other complex types you can use a stringstream like this:
std::ostringstream stream;
stream << "Hello, " << nameField;
stream << ", here is an int " << 7;
std::string text = stream.str();
Qt probably has its own string types, which should work in a similar fashion.
I would use a stringstream but I'm not 100% sure how that fits into your NSString case...
stringstream ss (stringstream::in);
ss << "hello my name is " << nameField;
I think QString has some nifty helpers that might do the same thing...
QString hello("hello ");
QString message = hello % nameField;
You could use QString::sprintf. I haven't found a good example of it's use yet, though. (If someone else finds one, feel free to edit it in to this answer).
You might be interested in seeing information about the difference between QString::sprintf and QString::arg.

C++ - string.compare issues when output to text file is different to console output?

I'm trying to find out if two strings I have are the same, for the purpose of unit testing. The first is a predefined string, hard-coded into the program. The second is a read in from a text file with an ifstream using std::getline(), and then taken as a substring. Both values are stored as C++ strings.
When I output both of the strings to the console using cout for testing, they both appear to be identical:
ThisIsATestStringOutputtedToAFile
ThisIsATestStringOutputtedToAFile
However, the string.compare returns stating they are not equal. When outputting to a text file, the two strings appear as follows:
ThisIsATestStringOutputtedToAFile
T^#h^#i^#s^#I^#s^#A^#T^#e^#s^#t^#S^#t^#r^#i^#n^#g^#O^#u^#t^#p^#u^#t^#
t^#e^#d^#T^#o^#A^#F^#i^#l^#e
I'm guessing this is some kind of encoding problem, and if I was in my native language (good old C#), I wouldn't have too many problems. As it is I'm with C/C++ and Vi, and frankly don't really know where to go from here! I've tried looking at maybe converting to/from ansi/unicode, and also removing the odd characters, but I'm not even sure if they really exist or not..
Thanks in advance for any suggestions.
EDIT
Apologies, this is my first time posting here. The code below is how I'm going through the process:
ifstream myInput;
ofstream myOutput;
myInput.open(fileLocation.c_str());
myOutput.open("test.txt");
TEST_ASSERT(myInput.is_open() == 1);
string compare1 = "ThisIsATestStringOutputtedToAFile";
string fileBuffer;
std::getline(myInput, fileBuffer);
string compare2 = fileBuffer.substr(400,100);
cout << compare1 + "\n";
cout << compare2 + "\n";
myOutput << compare1 + "\n";
myOutput << compare2 + "\n";
cin.get();
myInput.close();
myOutput.close();
TEST_ASSERT(compare1.compare(compare2) == 0);
How did you create the content of myInput? I would guess that this file is created in two-byte encoding. You can use hex-dump to verify this theory, or use a different editor to create this file.
The simpliest way would be to launch cmd.exe and type
echo "ThisIsATestStringOutputtedToAFile" > test.txt
UPDATE:
If you cannot change the encoding of the myInput file, you can try to use wide-chars in your program. I.e. use wstring instead of string, wifstream instead of ifstream, wofstream, wcout, etc.
The following works for me and writes the text pasted below into the file. Note the '\0' character embedded into the string.
#include <iostream>
#include <fstream>
#include <sstream>
int main()
{
std::istringstream myInput("0123456789ThisIsATestStringOutputtedToAFile\x0 12ou 9 21 3r8f8 reohb jfbhv jshdbv coerbgf vibdfjchbv jdfhbv jdfhbvg jhbdfejh vbfjdsb vjdfvb jfvfdhjs jfhbsd jkefhsv gjhvbdfsjh jdsfhb vjhdfbs vjhdsfg kbhjsadlj bckslASB VBAK VKLFB VLHBFDSL VHBDFSLHVGFDJSHBVG LFS1BDV LH1BJDFLV HBDSH VBLDFSHB VGLDFKHB KAPBLKFBSV LFHBV YBlkjb dflkvb sfvbsljbv sldb fvlfs1hbd vljkh1ykcvb skdfbv nkldsbf vsgdb lkjhbsgd lkdcfb vlkbsdc xlkvbxkclbklxcbv");
std::ofstream myOutput("test.txt");
//std::ostringstream myOutput;
std::string str1 = "ThisIsATestStringOutputtedToAFile";
std::string fileBuffer;
std::getline(myInput, fileBuffer);
std::string str2 = fileBuffer.substr(10,100);
std::cout << str1 + "\n";
std::cout << str2 + "\n";
myOutput << str1 + "\n";
myOutput << str2 + "\n";
std::cout << str1.compare(str2) << '\n';
//std::cout << myOutput.str() << '\n';
return 0;
}
Output:
ThisIsATestStringOutputtedToAFile
ThisIsATestStringOutputtedToAFile
It turns out that the problem was that the file encoding of myInput was UTF-16, whereas the comparison string was UTF-8. The way to convert them with the OS limitations I had for this project (Linux, C/C++ code), was to use the iconv() functions. To keep the compatibility of the C++ strings I'd been using, I ended up saving the string to a new text file, then running iconv through the system() command.
system("iconv -f UTF-16 -t UTF-8 subStr.txt -o convertedSubStr.txt");
Reading the outputted string back in then gave me the string in the format I needed for the comparison to work properly.
NOTE
I'm aware that this is not the most efficient way to do this. I've I'd had the luxury of a Windows environment and the windows.h libraries, things would have been a lot easier. In this case though, the code was in some rarely used unit tests, and as such didn't need to be highly optimized, hence the creation, destruction and I/O operations of some text files wasn't an issue.