Problems with garbage characters when reading file [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I'm having trouble reading data from a file, and concatenating selected parts of the data (text) into a buffer of my own.
The code is like follows:
char buffer[1000];
char* allNewData = (char *)malloc(10000);
while (! myfile.eof() )
{
myfile.getline (buffer, 1000);
pch = strstr (buffer,"bla bla");
if(pch == NULL)
{
char* temp = buffer;
strcat(allNewData, temp);
strcat(allNewData, "\n");
}
else
{
strcat(allNewData, "here's bla bla");
strcat(allNewData, "\n");
}
}
cout<<allNewData<<endl;
When I run the program, allNewData first has some garbage text, followed by the proper/expected results, like this:
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii <-rubbish data
hello <- actual data
I need to get rid of this rubbish data, how can I change the code to achieve this?

You need to clear your newly allocated buffer before using string concatenation functions. They expect a valid string, to be able to find the end and thus the start of where to concatenate.
Use:
allNewData[0] = '\0';
this makes allNewData into an empty string. Do this before the loop, before you start concatenating all the found data.
Also, your code needs to better take care of the various "gotchas" when it comes to I/O and handling memory:
Don't check for EOF before doing a read access.
Check that the read was successful, before using the results of the read.
Make sure you don't exceed the capacity of your buffer when storing data.

Some comments, which you may find helpful or disregard:
What if there is a line longer than 1000 characters? (and say, that 1001-1008 is 'blah blah')? The line will be split into two in your new file and there will be an extra line before "here's blah blah"? Is this now a bug or desired functionality?
What if the line is longer than 1000, but "blah" is 996-1000 and the second "blah" is on the second segment - now you've lost one
What if your file is longer than 10000 characters?
They may sound like trivial questions, but answering them correctly will mean that you'll have to change your approach, I suggest purer C++ approach:
ifstream f_in(<file>);
ostringstream s_out;
string line;
while(f_in.good())
{
getline(f_in, line); // global getline function in <string>
if (line.find("blah blah") != string::npos)
{
s_out << "here's blah blah" << endl;
}
else
{
s_out << line << endl;
}
}
This way you don't have to worry about any of the questions above...

You can also use a combination of getline and ignore

Again... you have to check that your IO operation don't fail and eof() should be used only after a failed IO operation.

Related

Reading string from vector until whitespace in C++ [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
This is probably easy but im not sure how. I tried searching multiple websites and yes Google and couldn't find anything on this.
My vector result[0] looks like this
A3 * * B4 * *
Declaration
vector<string> result = v.formVectorFile("Prj3 Config.txt");
I know that cin reads until whitespace so I was trying to use this to figure it out.
If I read straight from fstream I can read until whitespace, but im trying to do this with a string inside a vector and something like result[0] >> s; obviously doesnt work.
I need to read until it hits a whitespace then read the next one until whitespace. Etc...
So extract A3 by itself. Operate on it then extract * etc...
Your question is unclear because you don't tell us precisely what result is.
If we can assume that result is a std::vector<std::string>, then you can do something like this:
std::istringstream iss(result[0]); // consider only first string in vector
std::string item;
while(iss >> item) {
std::cout << "I found: " << item << "\n";
}
If we assume that result is std::vector<char>, then you can do this:
std::string s(result.begin(), result.end()); // consider entire vector as single string
std::istringstream iss(s);
while(iss >> item) {
std::cout << "I found: " << item << "\n";
}

Transfer contents from C FILE to C++ stream [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Suppose I have a file opened with the C syntax
FILE* fp = fopen("whatever.txt", "w");
// Library function needs FILE* to work on
libray_function(fp);
// Now I'd like to copy the contents of file to std::cout
// How???
fclose(fp);
I would like to be able to copy the contents of that file in a C++ ostream (like a stringstream or maybe even std::cout). How can I do that?
You could use an ifstream and rdbuf():
#include <fstream>
#include <sstream>
std::ifstream in("whatever.txt");
std::ostringstream s;
s << in.rdbuf();
or:
std::ifstream in("whatever.txt");
std::cout << in.rdbuf();
You've opened the file for write. You're going to need to close it and reopen it anyway, you might as well open it however you please (as an istream if you like). Then it just depends how much you care about performance. If you actually care, you should read it in chunks (at least 512 bytes at a time). If you don't care about performance you can read one byte, spit out one byte.
Close it first.
fclose(fp);
Then open again
string line;
ifstream myfile ("whatever.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}

Validation for float in c++ [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am getting input as a float. For example if the user is entering in 3.5 then it works fine. If user enters in 3.X or any other characters it is causing an infinite loop. is there any way in which i can validate the variable so that user can enter only numbers? I am using gcc compiler.
The usual way is to read the data as a string, then convert it to a float, and see of the entire input string was consumed in that conversion. Boost lexical_cast (for one example) can automate most of that for you.
You don't give any sample code, so we can see what you're doing, but I
suspect from the symptoms that you're doing something like:
while ( ! input.eof() ) {
double d;
input >> d;
// do someting with d...
}
There are two problems with this: the first is that once an error occurs
(because 'X' cannot be part of a double), the stream memorizes the
error until it is explicitly cleared, so all following input also fails
(and no further characters are extracted from the string). When you
have a format error in a stream, it is necessary to reset the error
state before continuing.
The second problem with the above is that input.eof() doesn't mean
much until after input has failed; it's not a very useful function.
What you probably want to do is:
double d;
while ( input >> d ) {
// do something with d
}
This will stop reading on the first error. If you want to recover from
errors and continue, then you need something more elaborate:
double d;
while ( input >> d || !input.eof() ) {
if ( input ) {
// do something with d...
} else {
// format error...
input.clear(); // reset the error state...
// advance the stream beyond the error:
// read to next white space (or EOF), or at least
// advance one character.
}
}
Alternatively, it's often more robust to do as others have suggested,
read the input line by line, then scan the line:
std::string line;
while ( std::getline( input, line ) ) {
std::istringstream l( line );
double d;
if ( l >> d >> std::ws && d.get() == EOF ) {
// do something with d...
} else {
// format error...
// we don't have to clear or skip ahead, because we're
// going to throw out the istringstream anyway, and the
// error didn't occur in the input stream.
}
}
This imposes a much more rigorous format: one value per line, but if
you count the lines, you can output the line number in the error
message; the person who has to correct the bad input will appreciate
that.
try
{
double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }
from: How to determine if a string is a number with C++?
The best way for reading a double value from input and assuring it's well formed is reading the input as a string, and then parsing it using the standard strtod function included in the stdlib library.
For a more detailed explanation on some different possibilities when parsing that string you can check this other post.
Your post i somewhat unclear, but from what I understand, i think you should use strtof.
Get your data from the user as String, than use the function to convert to float and check if succeeded by comparing the pointers.
for more info check the man pages for strtof.

Converting console application to GUI [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I found a C++ code to convert Latitude/Langitude to UTM coordinate.
The code is here.
I would like to use .NET GUI (windows Forms) instead of the console screen.
Now instead of entering the value 22.2 33.3 for example in console, I would read it from a textBox. and then call the conversion function.
The problem that I faced is I don't know what parameters should I pass to the function
`CvtLine(int C, char**V, char*p)`
which is called from the main function of console application:
Code
int main(int argc, char**argv){ //2010-08-11: was void main(...
char buf[256]; char*p; int L,ac; char*av[129]; //vars for reading stdin
cout<<setiosflags(ios::fixed); //decided against including ios::showpoint
Fmt=fUT4|fLLD|fLLDM; //default for Fmt, if not specified by input
--argc; ++argv; //remove spurious first element of argv array
while(argc && memcmp(argv[0],"--",2)==0){ //handle leading options: --Outputformat, --test, --help
if (isdigit(argv[0][2])) Fmt=atoi(argv[0]+2); //for --<DIGIT>, parse Outputformat into Fmt
else if(strcmp(argv[0],"--test")==0) {Testcases(); return 0;} //for --test, run testcases & exit
else {Usage(); return 0;} //for --help, show Usage & exit
--argc; ++argv;
}
if(argc==0) while(cin.getline(buf,256), cin.good()){ //0 args, read stdin converting each line
p=buf; ac=0;
while(1){ while(*p&&strchr(" \t",*p))++p; if(*p==0||*p=='#')break; av[ac++]=p; while(*p&&!strchr(" \t#",*p))++p;} //break line into whitespace-separated words
if(ac>=2&&ac<=4) CvtLine(ac,av,p); //line with 2|3|4 words, convert and print
else if(ac==0) cout<<buf<<"\n"; //line with no words, echo the line (comments)
else cout<<"==invalid number-of-words: "<<buf<<"\n"; //anything else is invalid, produce errmsg
}
else if(argc>=2&&argc<=4) CvtLine(argc,argv,""); //2|3|4 args, convert and print
else Usage(); //argc other than 0|2|3 is invalid, show Usage
return 0; //2010-08-11: added when void became illegal
}
Take a look at the .NET Spatial Reference and Projection Engine library.
http://projnet.codeplex.com/
.NET Spatial Reference and Projection Engine
Proj.NET performs point-to-point coordinate conversions between geodetic
coordinate systems for use in fx. Geographic Information Systems (GIS)
or GPS applications.
It their FAQ, there is a code sample on converting between systems.
Projecting points from one coordinate system to another

how would one go about finding specific words in a text file in c++ [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
how would i do this:
Got a text file called directorycontents.txt in this directorycontents.txt there is a bunch of text each one is a filename with a filename extension i want to be able to go like this if there is a filename extension of specific characters like .txt or .png then do fprintf(stderr,"whateva");
i have looked at istream and fstream and iostream but im not really shore how to use fstream to do this
thanks
Okay, I'll just point you to the right direction and I won't post any code, as you need to try it by yourself.
First of all, read about reading files in C++. You can google it and there are tons of information about this. You can try with "how to read text file in C++", for example.
Second, prefer using ofstream and/or ifstream - this is the C++ way to do it.
Then parse the file - you can read it word by word (using istream::operator>> ) , line by line (for example with getline ) into std::string (as you're talking about file names).
And then analize the input - analize the parsed file and search for specific words in it - for example, std::string has member functions like find - I think this will be enough for your problem :)
I hope that helps. Just note, that we don't write code here, we just help finding solutions for problems.
For something like this definitely take a look at std::fstreams. Based on your vague description of what you're trying to do, you can use this simple program as a starting point:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void doSomething();
int main(int argc, char *argv[])
{
if(argc < 2)
{
cout << "Usage: findsomething [filename]" << endl;
return 1;
}
ifstream infile(argv[1], ifstream::in);
if(!infile.is_open())
{
cout << "Couldn't open file " << argv[1] << endl;
return 1;
}
string line;
while(getline(infile, line))
{
if(line.find(".txt") != string::npos ||
line.find(".png") != string::npos ||
line.find(".bat") != string::npos)
{
doSomething();
}
}
}
Hopefully, that's enough code to get you started and it isn't too difficult for you to read.