I am having a little bit of a dilemma. I have an input file that can have a number 1 through 9 or a asterisk. I am treating 1-9 as a character. I don't know if there is white space or new lines. I can't use >> because I don't know if there is white space. I can't use get() because it will stop reading in characters if get encounters a new line. Could someone give me some suggestions?

Recommended Answers

All 6 Replies

Generally speaking, if you're not sure of the contents of the file, or if it may contain undesired characters, you should consider reading a line of the file into a string variable or char array, and then cleaning it up (removing leading/trailing spaces, CR/LF, etc.). Then you can look at converting the string/char data to a form that your program can use.

Additionally, you can also paste some of your file contents here, and any code you have here, we can give you better ideas on how to proceed.

This is what I came up with, but the output is all zeros

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

int main(int argc, char *argv[])
{
	//Testing for correct number of arguments at command line
	if(argc != 3)
	{
		cout << "ERROR--Not enough arguements!!" << endl;
		cout << "The correct format is: \"./name of program\" \"input file\" \"output file\"" << endl;
		//exit(1);  change at submission
	}
	
	//opening data file from user at run time
	ifstream infile;
    infile.open(argv[1]);
	
	if(infile.fail())
	{
		cout << "Failed to open input file." << endl;
		exit(1);
	}

	ofstream outfile;
    outfile.open(argv[2]);
	
	if(outfile.fail())
	{
		cout << "Failed to open output file." << endl;
		exit(1);
	}

	const int SIZE = 81;

	int board[SIZE];
	char input[1];
	
	for(int i = 0; i < 9; i++)
	{
		for(int j = 0; j < 9; j++)
		{
			if (infile.peek()=='\n') 
			    infile.ignore(1,'\n');
			else if (infile.peek()==' ') 
			    infile.ignore(1,' ');
			infile.get(input, 1);
			board[i*9+j] = atoi(input);
		}
	}
	
	for(int i = 0; i < 9; i++)
	{
		for(int j = 0; j < 9; j++)
		{
			cout << board[i*9+j];
		}
		cout << endl;
	}
	cout << endl;
	system("pause");
	return 0;
}

input file

* 1 * 4 * * * * 2
* * 4 * 7 2 * * *
* 8 3 * * 5 * 7 *
* 3 8 2 * 7 * * *
* 5 2 1 * 4 8 3 *
* * * 5 * 3 7 2 *
* 2 * 3 * * 9 4 *
* * * 7 2 * 6 * *
9 * * * * 6 * 1 *

I am having a little bit of a dilemma. I have an input file that can have a number 1 through 9 or a asterisk. I am treating 1-9 as a character. I don't know if there is white space or new lines. I can't use >> because I don't know if there is white space. I can't use get() because it will stop reading in characters if get encounters a new line. Could someone give me some suggestions?

No, get will read in a newline character as a newline character. Not sure what you mean by "stops". If you use get to read in a char, it "stops" after every character.

ifstream ins;
char c;
ins.get (c);

Also, are you trying to save the spaces and newlines or you just want to ignore them? If you need to save them, you're right, don't use >>. If you want to ignore spaces and newlines, which it looks to me like you want to, >> is perfect.

This is what I came up with, but the output is all zeros

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

int main(int argc, char *argv[])
{
	//Testing for correct number of arguments at command line
	if(argc != 3)
	{
		cout << "ERROR--Not enough arguements!!" << endl;
		cout << "The correct format is: \"./name of program\" \"input file\" \"output file\"" << endl;
		//exit(1);  change at submission
	}
	
	//opening data file from user at run time
	ifstream infile;
    infile.open(argv[1]);
	
	if(infile.fail())
	{
		cout << "Failed to open input file." << endl;
		exit(1);
	}

	ofstream outfile;
    outfile.open(argv[2]);
	
	if(outfile.fail())
	{
		cout << "Failed to open output file." << endl;
		exit(1);
	}

	const int SIZE = 81;

	int board[SIZE];
	char input[1];
	
	for(int i = 0; i < 9; i++)
	{
		for(int j = 0; j < 9; j++)
		{
			if (infile.peek()=='\n') 
			    infile.ignore(1,'\n');
			else if (infile.peek()==' ') 
			    infile.ignore(1,' ');
			infile.get(input, 1);
			board[i*9+j] = atoi(input);
		}
	}
	
	for(int i = 0; i < 9; i++)
	{
		for(int j = 0; j < 9; j++)
		{
			cout << board[i*9+j];
		}
		cout << endl;
	}
	cout << endl;
	system("pause");
	return 0;
}

input file

* 1 * 4 * * * * 2
* * 4 * 7 2 * * *
* 8 3 * * 5 * 7 *
* 3 8 2 * 7 * * *
* 5 2 1 * 4 8 3 *
* * * 5 * 3 7 2 *
* 2 * 3 * * 9 4 *
* * * 7 2 * 6 * *
9 * * * * 6 * 1 *

You can read in a character at a time, rather than read in an entire string. The spaces are no longer an issue if you read from the file into a character rather than a string. Here you have defined the variable you are reading into a character array of length 1:

char input[1];
// code
infile.get(input, 1);

Just make input a char.

char input;
// code
infile.get(input);

But frankly I think you are making it more complicated than it needs to be. You mentioned that you want to store 1 - 9 as characters, as well as store the asterisk as a character, but you have board defined as an integer array, then you are trying to do something with atoi. If I understand what you are trying to do correctly, all you need to do is this:

char board[SIZE];
	
	for(int i = 0; i < 9; i++)
	{
		for(int j = 0; j < 9; j++)
		{
                       infile >> board[i * 9 + j];
		}
	}

No, get will read in a newline character as a newline character. Not sure what you mean by "stops". If you use get to read in a char, it "stops" after every character.

ifstream ins;
char c;
ins.get (c);

I was a little confused on what get() could do. I thought it would stop reading characters at a newline.

Also, are you trying to save the spaces and newlines or you just want to ignore them? If you need to save them, you're right, don't use >>. If you want to ignore spaces and newlines, which it looks to me like you want to, >> is perfect.

You can read in a character at a time, rather than read in an entire string. The spaces are no longer an issue if you read from the file into a character rather than a string. Here you have defined the variable you are reading into a character array of length 1:

char input[1];
// code
infile.get(input, 1);

Just make input a char.

char input;
// code
infile.get(input);

I want to ignore spaces, but I don't know if the file will contain spaces. I cannot make any assumptions on how the input file is formatted.


But frankly I think you are making it more complicated than it needs to be. You mentioned that you want to store 1 - 9 as characters, as well as store the asterisk as a character, but you have board defined as an integer array, then you are trying to do something with atoi. If I understand what you are trying to do correctly, all you need to do is this:

char board[SIZE];
	
	for(int i = 0; i < 9; i++)
	{
		for(int j = 0; j < 9; j++)
		{
                       infile >> board[i * 9 + j];
		}
	}

I have to read the file as characters because I need to input the asterisk. Then I'm using atoi() to convert the characters to integers. Also if atoi() comes across a character that it does not know how to convert, it will convert it to a zero which I need.

I want to ignore spaces, but I don't know if the file will contain spaces. I cannot make any assumptions on how the input file is formatted.

>> ignores spaces and newlines. Thus if each element of your matrix is a single asterisk or digit, >> is perfect for your needs. If a number can be two or more digits, >> with a char won't be as good.

I have to read the file as characters because I need to input the asterisk. Then I'm using atoi() to convert the characters to integers. Also if atoi() comes across a character that it does not know how to convert, it will convert it to a zero which I need.

Fine, but how are you STORING the data? As an integer array or as a char array? As I said above, if all the data is singe digits or an asterisk, you can read it in as a char with the >> operator. No need to use atoi. A quick conversion from char to int would do fine. You could also use atoi too. If you are storing it as an integer array, you can read it in to a dummy char variable, then convert and store in in the integer array. There's more than one way to do this.

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.