Hi,

Please help...

I am trying to read in a file in C++ and when I use getline I am not able to read in the last line when the last line in the input file does not have a newline (\n) at the end. How do I do this?

I am reading a file with getline as such:

if (file.is_open())
{

//get first line 

getline (file,line);

//do something  - write output
}

Well you could put a blank line underneath in a text editor. It would save a lot of time. I take it your using a loop to keep reading the lines?

Works ok for me. Maybe there is something else wrong with the way your program is reading the file. Try this little program to see if it works with your text file.

#include<iostream>
#include <fstream>
#include<string>
#pragma warning(disable: 4996)

int main()
{
    std::string line;
    std::ifstream in("TextFile1.txt");
    while( getline(in,line) )
        std::cout << line << '\n';
}

Well you could put a blank line underneath in a text editor. It would save a lot of time. I take it your using a loop to keep reading the lines?

In testing I was already able to do this but I'm not able to add a line to the file as the file is not under my control.

Works ok for me. Maybe there is something else wrong with the way your program is reading the file. Try this little program to see if it works with your text file.

#include<iostream>
#include <fstream>
#include<string>
#pragma warning(disable: 4996)

int main()
{
    std::string line;
    std::ifstream in("TextFile1.txt");
    while( getline(in,line) )
        std::cout << line << '\n';
}

Thanks,

Hmm... I tried your example and didn't have the problem... Do you think it is because of getline being evaluated in the while loop? I am going to change some things and try it out.

I just changed my code but it is still not working. It is still overlooking the last line.

I tried this and when I have ios_base::badbit I get no data. Any idea on how to handle?

ifstream inputFile("file.txt", ios_base::eofbit | ios_base::badbit );

If I take out the ios)base::badbit and leave in ios_base::eofbit I still get the same problem with getline() not reading the last line.

Post the entire code (or function if its a large program) so we can see what you are doing.

Post the entire code (or function if its a large program) so we can see what you are doing.

Here is the code: We are writing a sic compiler for class. The code is working as planned until the last line of the file.

int main(int argc, char* argv[])
{
	cout << argv[1];
	ifstream inputFile("sic.txt", ios_base::eofbit );
        
        ProcessFiles(inputFile,outputFile);


}


void ProcessFiles(ifstream &file, ofstream &outfile)
{
	//struct symbol_tbl st[maxline];
	
	//input file is fixed length
	string codeLabel; //6+null
	string mneumonic; //5+null
	string instruction; //8+1null
	string codeLine;
	string address;
	//string temp;
	string get_op_code;
	string fixedLocator;
	string Result;

	st_length = 0;
	int st_cntr = 0;
	int count = 0;
	int getformat = 0;
	//long longAddress=4096.00;
	long longAddress=0;

	char hexLocctr[5];
	char * pch;
	string line;


	if (file.is_open())
	{

		while( getline(file,line))
		{
		//get first line 

		//getline (file,line);

		codeLabel = line.substr(0,6);
		mneumonic = line.substr(7,5);

		if (!mneumonic.find("END")==1)
		{
			cout << "Test";
		}

		if (line.length() > 14)
		{
			instruction = line.substr(14);
		}
		else if (line.length() < 15)
		{
			instruction = " ";
		}

		if (!mneumonic.find("START"))
		{
			/*update symbol table*/
			//address = instruction;	
			longAddress = longAddress + atoi(instruction.c_str());
			//st_cntr =  update_symbol_tbl(st_cntr, codeLabel, address);
			st[count].label = mneumonic;
			st_length = st_length + 1;
 			stringstream ss;
               ss << hex << instruction;
               ss >> start_address;
               locctr = start_address;
			pgm_file_name = codeLabel;
			int position = pgm_file_name.find_first_of(0x20);   //eliminate spacebar in filename
			pgm_file_name = pgm_file_name.substr(0, position);
		}
		else
		{
			locctr = 0;
		}

		// save start_address
		start_address = locctr;

		// save locctr in symbol table
		ultoa(locctr, hexLocctr, 16);
		fixedLocator = toHexString(hexLocctr,4).c_str();
		st[count].address = fixedLocator;

		//output to intermediate file
		//write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, locctr," ");
		write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, locctr," "); //first instruction =hex 1000
		
		while ( file.good())
		{
			// read next
			getline (file,line);

			if (!(file.good()))				// mk
				break;					// mk

			//this handles the comment lines, write the comments to the output file, do not update locctr
			if (line[0]== '.')				
			{
				// the space is the locctr - this is blank when 
				line = "     " +line + "\n";
				outfile.write(line.c_str(),line.length()); 
			}
			else
			{
				//get fixed length substrings
				codeLabel = line.substr(0,6);
				mneumonic = line.substr(7,5);

				if (line.length() > 14)
				{
					instruction = line.substr(14);
				}
				else if (line.length() < 15)
				{
					instruction = " ";
				}
					

				/*update symbol table*/
				if (codeLabel > " ")
				{
					/* search opcode table for format nbr*/
					string str1 = " "; 
					for (count = 0; count < op_length; count ++)
					{
						str1 = op[count].mnemonic;
						//if (st[count].label.find("BYTE") || st[count].label == "RESW  " || st[count].label == "RESB  ")
						//{
						//		//cout << "******************this works!";
						//		getformat = 3;
						//}
						//else 
							if (str1 == mneumonic)
						{
							getformat = op[count].format;
							//locctr = locctr + op[count].format;
							//string Result;
							//ostringstream convert;
							//convert << locctr;
							//Result = convert.str();
							////address = address + Result;
							//longAddress = longAddress + atoi(Result.c_str()); //adding
							get_op_code = op[count].op_code;
							break;
						}
						else if (count == 56 && str1 == mneumonic)
						{
							error_rtn(pass, locctr, 6);   // invalid operation requested
						}
					} //end for
					
					/* search symbol table for duplicate if Label exists*/
					if (codeLabel != "      ")
					{
						for (count = 0; count < st_length; count++)
						{
							//st_cntr =  update_symbol_tbl(st_cntr, codeLabel, address);
							if (st[count].label == codeLabel)
							{
								error_rtn(pass, locctr, 5);   // duplicate error on symbol table
							}
							//else if (st[count].label == "      ")
							else if (st[count].label == "")
							{
								break;
							}
						} // end for
						// if duplicate not found update symbol table
						st[count].label = codeLabel;

						// convet to hex & update symbol table
						ultoa(locctr, hexLocctr, 16);
						fixedLocator = toHexString(hexLocctr,4).c_str();
						st[count].address = fixedLocator;	
						st_length = st_length + 1;
					}
				
				//adds 1000 hex (4096 decimal) if the mneumonic is RESB --working
				if (!mneumonic.find("RESB"))
				{
					// create long address for output file
					ostringstream convert;
					convert << locctr;
					Result = convert.str();
					longAddress = longAddress + atoi(Result.c_str()); 

					//output to intermediate file
					write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, longAddress, get_op_code);
					getformat = atoi(instruction.c_str()); // 3 + # FROM INSTRUCTION 
					locctr = locctr + getformat;


				}else if(!mneumonic.find("RESW")) 
				{
					write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, 0," ");	
					getformat = 3 * atoi(instruction.c_str()); // 3 * # FROM INSTRUCTION 
					locctr = locctr + getformat;
			
				}else if(!mneumonic.find("BASE")) 
				{
					write_output_to_intermediate_file (outfile, 0, codeLabel, mneumonic, instruction, 0," ");	

				}else if(!mneumonic.find("BYTE")) 
				{
					write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, 0," ");	
					
					if (instruction.substr(0,2)=="X'")
					{
						getformat=1;
					}else if (instruction.substr(0,2)=="C'")
					{
						getformat=3; //working 	
					}
					locctr = locctr + getformat;
			
				}else if(!mneumonic.find("WORD")) 
				{
					write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, 0," ");	
					getformat = 3; // ADD 3 FROM INSTRUCTION 
					locctr = locctr + getformat;
			
				}else  //do standard output
				{

					// create long address for output file
					ostringstream convert;
					convert << locctr;
					Result = convert.str();
					longAddress = longAddress + atoi(Result.c_str()); 

					//output to intermediate file
					write_output_to_intermediate_file (outfile, locctr, codeLabel, mneumonic, instruction, longAddress, get_op_code);
					// update locctr to next statement location 
					locctr = locctr + getformat;	
				}
							
				} // end if
			
			} //end else

		} // end while

	}//end while-getline()
	} // end if
} /* end ProcessFiles()*/

>>ifstream inputFile("sic.txt", ios_base::eofbit );

Huh??? I've never seen anyone use eofbit in that context. That might be what's causing the problem. Just use ifstream inputFile("sic.txt"); Change the loop beginning on line 98 to use while(getline(file,line))

>>ifstream inputFile("sic.txt", ios_base::eofbit );

Huh??? I've never seen anyone use eofbit in that context. That might be what's causing the problem. Just use ifstream inputFile("sic.txt"); Change the loop beginning on line 98 to use while(getline(file,line))

I tried the changes, but I don't even get to this point unless I add a newline to the end of the file. And If I add the newline further down in the code wouldn't I be getting the next line when processing the file?


My last line in my file is this line (without quotes)

"       END    FIRST"

I'm not getting to this point unless I add a newline:

if (!mneumonic.find("END")==1)
		{
			cout << "Test";
		}

find() doesn't return 0 if the substring is not found -- it returns std::string::npos, which is defined as -1 (but may be defined as something else by other compilers). In any event, if (!mneumonic.find("END")==1) is wrong. Use this: if (mneumonic.find("END") == string::npos)

Thanks for the help. I'm going to have to reevaluate some things in the program. It was worked on by a group so I am going to step through everything again to try to find the issue.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.