Sign in to follow this  

do not ignore Mr blank

This topic is 4659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey there. (ok this may sound like a silly question for you code gurus) I have this little app writen in c++ that simply ads the contents of 2 files together so it matches up names, when i read each line from a file into a buffer, how do i stop it ignoring blank lines? here are the contents of the 2 files: file 1: 095e5189r2.tif 1000e0097r3.tif <---note the blank lines 1000e0190r2.tif 1000e0210r4.tif 1000e1000r0.tif 1000m0060r3.tif 1000s0020r3.tif 1001000001ra.tif 1001c0001rb.tif 1001c0002rb.tif 1001c0003rb.tif 1001c0004r0.tif 1001c0005r1.tif file 2: <---note the blank lines 1000e0097r3.dgn <---note the blank lines 1000e0190r2.dgn 1000e0210r4.dgN 1000e1000r0.dgn 1000m0060r3.dgn 1000s0020r3.dgn 1001000001ra.dwg 1001c0001rb.dwg 1001c0002rb.dwg 1001c0003rb.dwg 1001c0004r0.dgn 1001c0005r1.dgn this is the app

#include <iostream>
#include <fstream>
using namespace std;

ifstream	inFile("c:\\image.txt");
ifstream	inFile2("c:\\file.txt");
ofstream	outFile("c:\\result.txt",ios::out);


int main()
{
    int k=0;  
	char buffer[10];
	char name[7];
	char name2[7];
	while(inFile)
	{
		
        inFile >> buffer;
		for(k=0;k<=7;k++){name[k] = buffer[k];};
		
		inFile2 >> buffer;
		for(k=0;k<=7;k++){name2[k] = buffer[k];};
	
		//cout << buffer << endl;
		//cout << name << endl;
		//outFile << buffer << endl;
		
        for(k=0;k<=7;k++){ outFile << name[k]; };
        outFile << " ";
        for(k=0;k<=7;k++){ outFile << name2[k]; }; // write that file name to new file
		outFile << endl;
	}

	system("pause");
	return 0;
}

(please excuse the crappyness of my code, i am new to cpp) the result: 795e51891 1000e0097 0000e0091 1000e0190 0000e0191 1000e0210 0000e0211 1000e1000 0000e1001 1000m0060 0000m0061 1000s0020 0000s0021 100100000 100100001 1001c0001 2001c0001 1001c0002 3001c0001 1001c0003 4001c0001 1001c0004 5001c0001 1001c0005 all the data is kinda skrewed up i know, im pretty sure i can hack that but what i want is for the data to line up; 095e5189r2 <---like this 1000e0097r3 1000e0097r3 <---and this 1000e0190r2 1000e0190r2 1000e0210r4 1000e0210r4 1000e1000r0 1000e1000r0 1000m0060r3 1000m0060r3 1000s0020r3 1000s0020r3 1001000001r 1001000001ra 1001c0001rb 1001c0001rb 1001c0002rb 1001c0002rb 1001c0003rb 1001c0003rb 1001c0004r0 1001c0004r0 1001c0005r1 1001c0005r1 Any help at all would be much appreciated.

Share this post


Link to post
Share on other sites
Some comments about your code:


  • Your code is, mostly, C code. The only C++ construct you use is streams, and you do it in an either usafe or putchar() manner.


  • (stream) >> (char buffer) is unsafe. Were you to read 11-character lines (such as the line "1001000001ra"), you would overflow the buffer and wreak havoc on your entire application.


  • Your use of the magic constant "7" to truncate your string is somewhat disturbing. What if your strings are more than 7 characters long? You'd have to run through the entire code understanding what "7" means the length of the string and what "7" doesn't. Bad practice.


  • I suggest you use strings, not character arrays, to represent strings. Especially std::string.


  • When you create an array of size 7, do not try to access indices 0-7 as this will cause an overflow. Only indices 0-6 are available.




Below is the code using std::string. Portable, doesn't make any assumptions about the lengths of the files or whatever.


#include <string>
#include <fstream>
#include <istream>

using namespace std;

// helper function: removes the ".xxx" in a string
void truncate( string & s ) {

string::size_type occurence = s.find( '.' );
if( occurence < s.size( ) ) { s.erase( occurence ); }
}

// main function
int main( void ) {

// open streams
ifstream inFile("image.txt");
ifstream inFile2("file.txt");
ofstream outFile("result.txt",ios::out);

// the last set of lines read
string line1, line2;

while( true ) {

// read the next lines from the files
getline( inFile, line1 );
getline( inFile2, line2 );

// nothing left to read? exit the loop
if( !(inFile || inFile2) ) { break; }

// remove the ".xxx"
truncate( line1 );
truncate( line2 );

// output the two lines
outFile << line1 << " " << line2 << endl;
}

return 0;
}

Share this post


Link to post
Share on other sites
Now that your problems are solved:

(stream) >> (character buffer or string) reads a "token" off the stream (basically, a word). It will skip over whitespace, and then stop reading at the next bit of whitespace. That includes newlines.

To read the current line, you need to make use of an appropriate 'getline' function. For std::string instances, you use the free function std::getline, which takes as arguments the stream to read from and the std::string to read into (and optionally, a delimiter character for the "end of line", which defaults to a newline). For character buffers, you would use the stream's getline member function: stream_name.getline(buffer_name). In either case, the function returns a reference to the stream that was read from, so you can use the call in an if statement (or anywhere else a conditional is required) to see if the stream is still "good" after the read.

I would write the code slightly differently:


#include <string>
#include <fstream>
#include <iostream>

using namespace std;

// helper function: remove extension from 'filename' string, and return the result.
inline string truncate(const string & s) {
return string(s, 0, s.find('.'));
}

// Toohr: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.4
int main() {
// open streams
ifstream inFile("image.txt");
ifstream inFile2("file.txt");
ofstream outFile("result.txt");

// the last set of lines read
string line1, line2;

// while able to read a line from each file
while(getline(inFile, line1) && getline(inFile2, line2)) {
// output the two lines that were read, with appropriate formatting.
outFile << truncate(line1) << " " << truncate(line2) << endl;
}
}

Share this post


Link to post
Share on other sites
To remove the file extension you want to remove everything following the last '.' character, as there might be more than one or be part of a directory name. If a '/' or '\\' character appears anywhere after it, you want to leave it alone. You also want to leave it alone if the '.' character appears right after a '/' or '\\' character or is at the start of the string, otherwise you get an empty string or a directory name instead of a file name.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
// while able to read a line from each file


That should be "from at least one file" I believe. You have to fill with blanks when there's something left to read from the other file.

Also, your code is less readable to the uninitiated ;)

Share this post


Link to post
Share on other sites

This topic is 4659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this