search printf statement in file and replace with string value - c++

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.

Related

Printf display only one word

I want to display more than one word using printf, Do I should change first parameter in pritnf?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int value;
printf("How many:"); scanf("%d", &value);
char* arr1 = new char[value];
scanf("%s[^\n]", arr1);
printf("%s", arr1);
delete [] arr1;
return 0;
}
As already pointed out in the comments section, the following line is wrong:
scanf("%s[^\n]", arr1);
The %s and %[^\n] are distinct conversion format specifiers. You seem to be attempting to use a hybrid of both. If you want to read a whole line of input, you should use the second one.
However, even if you fix this line, your program will not work, for the following reason:
The statement
scanf("%d", &value);
will read a number from standard input, but will only extract the number itself from the input stream. The newline character after the input will not be extracted.
Therefore, when you later call
scanf("%[^\n]", arr1);
it will extract everything that remained from the previous scanf function call up to the newline character. This will result in no characters being extracted if the newline character immediately follows the number (which is normally the case).
Example of program's behavior:
How many:20ExtraInput
ExtraInput
As you can see, everything after the number up to the newline character is being extracted in the second scanf function call (which is then printed). However, this is not what you want. You want to extract everything that comes after the newline character instead.
In order to fix this, you must discard everything up to and including the newline character beforehand. This must be done between the two scanf function calls.
#include <stdio.h>
int main()
{
int value;
int c;
printf("How many:"); scanf("%d", &value);
char* arr1 = new char[value];
//discard remainder of line, including newline character
do
{
c = getchar();
} while ( c != EOF && c != '\n' );
scanf("%[^\n]", arr1);
printf("%s", arr1);
delete [] arr1;
return 0;
}
The program now has the following behavior:
How many:20ExtraInput
This is a test.
This is a test.
As you can see, the program now discards ExtraInput and it correctly echoes the line This is a test.

C Builder (C++) AnsiString Length method

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();
}

File read and write while reading the file line by line

Program:
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
FILE *f;
char* line;
size_t ln=100;
char* s;
line=new char[100];
s=new char[100];
cout<<"input key"<<endl;
cin>>s;
f=fopen("parvin.txt","r");
if(f==NULL)
{
cout<<" no file TO read so creating for writing "<<endl;
//return 0;
f=fopen("parvin.txt","w");
fputs(s,f);
fputc('\n',f);
}
else
{
while(! feof(f))
{
fgets(line,100,f);
cout<<line<<endl;
//if(!strncmp(line,s,strlen(line)-1))
if(strcmp(line,s)== 0 )
{
cout<<"duplicate found"<<endl;
fclose(f);
return 0;
}
}
fclose(f);
f=fopen("parvin.txt","a+");
fputs(s,f);
fputc('\n',f);
}
fclose(f);
}
Here the above program where I like to read an input string and write it into file provided the string is not present already in file.
take input string
open file in read mode.
if it is first time entry file will not be there if file pointer return NULL, create a file to write mode and write the
inputted string.
if file already there then read file line by line and compare with input string if match with any line then return and close.
other wise open the same file in write mode and write the inputted string.
But it is not working properly..
strcmp not executing properly.... with the duplicate entry also it
dont go into that loop of "duplicae found" .
please if anyone can help ...
The fgets:
fgets(line,100,f);
consumes the newline character from f and stores it in line. But s doesn't contain the newline character. So, the strcmp returns a non-zero number as the strings(s and f) are different.
Strip the newline character by using
line[strcspn(line, "\n")] = '\0';
just after the fgets. The strcspn function, in your case, returns the number of characters until a \n in line. If \n is not found in line, it returns the length of the string line(strlen(line)).
Also, read Why is while ( !feof (file) ) always wrong?. Replace
while(!feof(f))
with
while(fgets(line,100,f)) //Same as `while(fgets(line,100,f) != NULL)`
and don't forget to remove the fgets from the body of the loop to fix this issue.
Use
while(fgets(line,100,f)!=NULL)

How to read content of the file and save it to string type variable? Why there is empty space?

This is how I get the name of the file from the command line and open a file and save the content of the file line by line to a string. All the procedures works fine except three empty spaces at the beginning of the file. Is anyone can say why these empty spaces occurred and how can I ignore them?
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
if(!fin.good()){
cout<<" = File does not exist ->> No File for reading\n";
exit(1);
}
string s;
while(!fin.eof()){
string tmp;
getline(fin,tmp);
s.append(tmp);
if(s[s.size()-1] == '.')
{
//Do nothing
}
else
{
s.append(" ");
}
cout<<s<<endl;
The most probable cause is that your file is encoded in something else than ASCII. It contains a bunch of unprintable bytes and the string you on the screen is the result of your terminal interpreting those bytes. To confirm this, print the size of s after the reading is done. It should be larger than the number of characters you see on the screen.
Other issues:
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
is quite an overzealous way to go about it. Just write ifstream fin(a.c_str());, or simply ifstream fin(a); in C++11.
Next,
while(!fin.eof()){
is almost surely a bug. eof() does not tell if you the next read will succeed, only whether the last one reached eof or not. Using it this way will tipically result in last line seemingly being read twice.
Always, always, check for success of a read operation before you use the result. That's idiomatically done by putting getline in the loop condition: while (getline(fin, tmp))

getline and file handling

I want to read the first lines of 2 separate files and then compare them...the following is the code i use but it gives me "istream to string error". do i need to use a while condition to start reading the files first?
ifstream data_real(filename.c_str()); /*input streams to check if the flight info
are the same*/
ifstream data_test("output_check.txt");
string read1, read2;
string first_line_input = getline(is,read1);
string first_line_output_test = getline(data_test,read2);
string test_string1, test_string2;
int num_lines_output_test, num_lines_input;
if((first_line_input.substr(0,3)==first_line_output_test.substr(0,3)))
{
while(!data_test.eof()) // count the number of lines for the output test file with the first flight info
{
getline(data_test,test_string1);
num_lines_output_test++;
}
while(getline(is,test_string2)) // count the number of lines for the output test file with the first flight info
{
if(test_string2.substr(0,3)!="ACM")
num_lines_input++;
else
break;
}
}
getline(istream, string) returns a reference to the istream, not a string.
So, comparing the first line of each file could be something like:
string read1, read2;
if !(getline(is,read1) && getline(data_test,read2)){
// Reading failed
// TODO: Handle and/or report error
}
else{
if(read1.substr(0,3) == read2.substr(0,3)){
//...
Also: Never use eof() as a termination condition for a stream reading loop. The idiomatic way to write it is:
while(getline(data_test,test_string1)) // count the number of lines for the output test file with the first flight info
{
num_lines_output_test++;
}
Try adding this helper function:
std::string next_line(std::istream& is) {
std::string result;
if (!std::getline(is, result)) {
throw std::ios::failure("Failed to read a required line");
}
return result;
}
Now you can use lines from the file the way you want (i.e. to initialize strings, rather than modify them):
string first_line_input = next_line(is);
string first_line_output_test = next_line(data_test);