C Builder (C++) AnsiString Length method - c++

I am used to program in c#, but now i had to help my roommate with a c++ project.
This is the "not working code" :
void HighlightKeyWords::Highlight(TRichEdit eMemo,TRichEdit RichEdit1)
{
ifstream file("KeyWords.txt");
AnsiString temp;
int maxWordLength=0;
if(file.is_open())
{
while(file>>temp)
{ if(temp.Length()> maxWordLength)
{
maxWordLength=temp.Trim().Length();
}
keyWords.push_back(temp);
}
file.close();
}
else
{
ShowMessage("Unable to open file. ");
}
for(unsigned i=0;i<KeyWords.size();i++)
{
richEdit1->Text=KeyWords[i];
}
eMemo->Text=MaxWordLength;
}
I get a list of keywords from the file. In MaxWordLength i want to know to maximum length of a word ( words are separated by new line in the text file ). When I do the temp.Length, i get 695 ( the number of all characters in the file ). Why am I not getting the actual length of the word i am adding to the vector?
Thank you!
LE: I also did the MaxWordLength logic in the for below, the for where i put the items in the RichEdit.

Use file.getline() instead of the >> operator, which won't produce the desired output in your case, but gives you the full file content as result. So AnsiString().Length() is not your problem. Just modify part of your code to get it working as intended:
char buffer[255];
if(file.is_open()){
while(file.getline(buffer, sizeof(buffer))){
temp = AnsiString(buffer).Trim();
if(temp.Length()> maxWordLength) maxWordLength=temp.Length();
keyWords.push_back(temp);
}
file.close();
}

Related

Why Does getline() Doesn't Read anything from a file?

I have made a code which accepts a txt file as input, and parse, and put them in 2d array myarray[][2].
Input file structure looks like this:
aaa/bbb
bbb/ccc
ccc/ddd
And it should be parsed like this:
myarray[0][0] = "aaa"
myarray[0][1] = "bbb"
myarray[1][0] = "bbb"
myarray[1][1] = "ccc"
The code which I made to do this:
void Parse_File(string file){
ifstream inFile;
inFile.open(file);
if (inFile.is_open()){
inFile.clear();
int lines = count(istreambuf_iterator<char>(inFile), istreambuf_iterator<char>(), '\n');
string myarray[lines][2];
int mycount = 0;
do{
getline(inFile, input);
myarray[mycount][0] = input.substr(0, input.find("/"));
myarray[mycount][1] = input.substr(input.find("/") +1, input.length());
mycount++;
}while (input != "");
}else{
Fatal_Err("File Doesn't Exist");
}
inFile.close();
}
But myarray doesn't have anything in it after this function. The do-while statement doesn't loop. I can't figure out why. Any help is appreciated. Thanks.
Your file had a few issues, but the major one was: You forgot to bring your file reading pointer back to the beginning of the text document. The count function took the said pointer to the end, so you needed to bring it back.
So you need to use the seekg() function to drag the pointer wherever you wish to.
See if the code below works for you
void Parse_File(string file)
{
ifstream inFile;
inFile.open(file);
if (inFile.is_open())
{
inFile.clear();
int lines = count(istreambuf_iterator<char>(inFile), istreambuf_iterator<char>(), '\n');
//Pitfall : By counting the lines, you have reached the end of the file.
inFile.seekg(0);// Pitfall solved: I have now taken the pointer back to the beginning of the file.
....
....//Rest of your code
}
}
Also, you need to learn debugging so that you understand your code more easily. I would recommend visual studio code for debugging c++.
Move "getline(inFile, input);" to the end of your loop and call it again right before you enter. input is probably "" before you enter the loop, so the loop is never called and input is never updated.

I can't load text from file properly

I can't seem to find what's wrong with this piece of code. It's a function that will load a couple of simple settings from a file. The problem is that the cout in the while loop doesn't show anything, only blank and an end line. It was put there for testing. Also the array "config_temp" only has blanks. I always used this method and even looked in previous projects and tutorials how it was written there. I can't find the expenation for this. Please help.
void load()
{
string config_temp[5];//temporary array into which the config is loaded to
int cc=1;//config counter
int ac=0;//array counter
ifstream file;
string line;
file.open("config.txt",ios::in);
while(getline(file,line))
{
if(cc%2!=1)
{
cout<<line<<endl;
config_temp[ac]=line;
ac++;
}
cc++;
}
file.close();
for(int i=0;i<=4;i++)
{
cout<<config_temp[i]<<endl;
}
frames=sti(config_temp[0]);
res_width=sti(config_temp[1]);
res_height=sti(config_temp[2]);
states=sti(config_temp[3]);
frequency=sti(config_temp[4]);
global_state=0;
}

Edit file line by line number - C++

I'm trying to edit a .dat file. I want to read a line by line number, turn the content to int, edit and replace it.
like I want to edit line number 23, it says "45" I need to make it "46". How do I do that?
ofstream f2;
theBook b;
f2.open("/Users/vahidgr/Documents/Files/UUT/ComputerProjects/LibraryCpp/LibraryFiles/Books.dat", ios::app);
ifstream file("/Users/vahidgr/Documents/Files/UUT/ComputerProjects/LibraryCpp/LibraryFiles/Books.dat");
cout<<"In this section you can add books."<<endl;
cout<<"Enter ID: "; cin>>b.id;
cout<<"Enter Name: "; cin>>b.name;
string sID = to_string(b.id);
string bookName = b.name;
string line;
int lineNumber = 0;
while(getline(file, line)) {
++lineNumber ;
if(line.find(bookName) != string::npos && line.find(sID) != string::npos) {
int countLineNumber = lineNumber + 4;
registered = true;
f2.close();
break;
}
}
Inside the file:
10000, book {
author
1990
20
20
}
If your file is small (such as under 1GB), you can just read the entire file into memory line-by-line as a std::vector<std::string> (Hint: use std::getline). Then, edit the required line, and overwrite the file with an updated one.
Iterate Byte for Byte through the file and count line breaks (\n or \r\n on Windows).
After 22 breaks, insert bytes that say “46”. It should overwrite the existing bytes.
If your modifications are the exact size of the original text, you can write back to the same file. Otherwise, you will need to write your modifications to a new file.
Since your file is variable length text, separated by newlines, we'll have to skip lines until we get to the desired line:
const unsigned int desired_line = 23;
std::ifstream original_file(/*...*/);
std::ofstream modified_file(/*...*/);
// Skip lines
std::string text_line;
for (unsigned int i = 0; i < desired_line - 1; ++i)
{
std::getline(original_file, text_line);
modified_file << text_line << std::endl;
}
// Next, read the text, modify and write to the original file
//... (left as an exercise for the OP, since this was not explicit in the post.
// Write remaining text lines to modified file
while (std::getline(original_file, text_line))
{
modified_file << text_line << std::endl;
}
Remember to write your modified text to the modified file before copying the remaining text.
Edit 1: By record / object
This looks like an X-Y problem.
A preferred method is to read in the objects, modify the object, then write the objects to a new file.

Arduino opening SD filename as string

I am trying to open up a file that I calculate the name into a string. However, it is just giving me compile errors as shown.
for(int i=1;;i++)
{
String temp = "data";
temp.concat(i);
temp.concat(".csv");
if(!SD.exists(temp))//no matching function for call to sdclass::exists(String&)
{
datur = SD.open(temp,FILE_WRITE);
}
}
I am a java person, so I don't see why this isn't working. I tried a few string object methods but none seem to have worked. I am a bit new at arduino programming but I understand java much better. The point of this for loop is to make a new file each time the arduino reboots.
SD.open expects a character array instead of a String, you need to convert it using the toCharArray method first. Try
char filename[temp.length()+1];
temp.toCharArray(filename, sizeof(filename));
if(!SD.exists(filename)) {
...
}
Completed Code:
for(int i=1;;i++)
{
String temp = "data";
temp.concat(i);
temp.concat(".csv");
char filename[temp.length()+1];
temp.toCharArray(filename, sizeof(filename));
if(!SD.exists(filename))
{
datur = SD.open(filename,FILE_WRITE);
break;
}
}
You will find a number of functions take char arrays instead of strings.

search printf statement in file and replace with string value

I am trying to replace all printf statements with a string value. So first, I am reading all lines to a string as below:
ifstream ifs;
ifs.open(filename);
string temp;
string text;
while(!ifs.eof())
{
getline(ifs, temp, '\t');
text.append(temp);
temp.clear();
}
Then I'm finding every line for printf and if it founds, than replacing it with a "printf statement".
My code for replacing printf :
char ch;
while(getline(is,check))
{
ch=check[0];
if(!isalpha(ch))
{
//statements..
}
else
{
string str2("printf");
size_t found;
found=check.find(str2);
if(found!=string::npos)
check="\n printf statement.\n";
OriginalStr.append(check);
check.clear();
}
It's working for three four line files like below:
main()
{
Hi i am Adityaram.
and i am good boy.
and you?
printf("");
{
printf("");
Aditya
printf("");
Rammm
printf("");
Kumar
printf("");
{
printf("");
printf("");
}
printf("");
}
printf("");
but not finding printf line in these lines of file.
main()
{
char ch, file_name[25],*p;
char answer[400];
int size=0;
FILE *fp;
printf("Enter the name of file you wish to see ");
gets(file_name);
}
Why it is not finding printf line? or how to do?
any suggestion would be appreciated.
Since this is a C program, you might have lines as:
{
or
}
ie. opening/closing a block. This is definitely not empty, but it will contain only 1 character. In your while i<6you are going way after the end of this buffer. So, add there a check that i is less than the length of the buffer.
Then it might happen that printf is not necessarily the first expression in the line, such as:
if(something) printf("this");
Your code is not picking this up. You will need to check for the "printf" as a substring in your wd. Look at http://www.cplusplus.com/reference/string/string/find/ for reference on finding strings in a string.
And last but not least, I don't see why you want your line to start with a letter (the check for isalpha). This will fail to change code like
{ printf("this"); }
And the reason that it works for small test files is because highly possibly you wrote them to pass your internal "test" but large files usually contain more widely used printf's.
Also, it is not mandatory that the indentation happens with tabs (\t) it might be simple spaces.
i got it, by this simple way:
string RemovePrintf(string value)
{
string RemovedPrintf,strP;
size_t poss;
value.insert(0," ");//insert a white-space, cause find method not returning position if it present at begin of string.
poss = value.find("printf"); // position of "printf" in str
strP = ""; // get insert whitespace at "printf line".
strP.resize(strP.length());
if((int)poss > 0)
RemovedPrintf.append(strP);
else
RemovedPrintf.append(value);
strP.clear();
RemovedPrintf.resize(RemovedPrintf.length());
return RemovedPrintf;
}
This works for both small files and large too.
By the way thanks for responding my question.