I am working on an assignment for my Data Structures and Algotithms in C++ class. My program will take a user input string and determine if it is a palindrome. I have to use stacks in this program. My program compiles with no errors but the following warning is displayed: "warning: NULL used in arithmetic" on lines 59 and 72 (I colored the 2 sections red). Can anyone please tell me why and what I need to do to correct this.

#include <fstream>		// to write to an output file
#include <iostream>		// to write to the screen/read from keyboard
#include <cassert>		// to make sure output file is opened correctly
#include <string>		// to allow for string functions
#include <cstdio>		// to allow low-level input
#include <cctype>		// to check for character types
#include <stack>		// the stack class

using namespace std;

ofstream outfile;

bool isOK(char ch);		// to make sure it is a valid character
bool isPalindrome(stack<char> &s1, stack<char> &s2);	// check for palindrome

void main()
{
	char letter, data[128], flag[3]="-1";
	int i, ch, length;
	stack<char> s1, s2, dummy;
	

	outfile.open("C:\\AlgProc C++ Palindrome.OUT");
	assert(!outfile.fail());

	cout << "Enter some characters and I'll see if it's a palindrome or "
		 << "enter -1 to quit.\n" << endl;
	for(i = 0;(ch = getchar())!='\n'&&i<128;i++)  // gets only proper characters
		data[i] = ch;   // puts characters into character array (string)
	data[i] = '\0';		// sets last cell to NULL string character
	while(strcmp(data, flag) != 0) // while data is not -1 to stop
	{
		length = i;

		while(!s1.empty())      // clear any existing data from the stacks
			s1.pop();
		while(!s2.empty())
			s2.pop();
		while(!dummy.empty())
			dummy.pop();

		for(i = 0; i < length; i++) // load s1 with the string
		{
			letter = toupper(data[i]);
			if(isOK(letter))
				s1.push(letter);
		}

		for(i = length; i > 0; i--) // load s2 with the reverse string
		{
			letter = toupper(data[i-1]);
			if(isOK(letter))
				s2.push(letter);
		}

		outfile << "\n\nThe following string was checked for being a palindrome:"
			    << endl << "   " << data << endl << endl
				<< "stack 1: ";
		while(!s1.empty()&& s1.top() != NULL)  // keep the "original" string
		{
			outfile << s1.top();		// use dummy for checking palindrome
			dummy.push(s1.top());
			s1.pop();
		}
		while(!dummy.empty())
		{
			s1.push(dummy.top());
			dummy.pop();
		}

		outfile << "\n\nStack 2: ";
		while(!s2.empty() && s2.top() != NULL)		{
			outfile << s2.top();
			dummy.push(s2.top());
			s2.pop();
		}
		while(!dummy.empty())
		{
			s2.push(dummy.top());
			dummy.pop();
		}

		outfile << "\n\nAs you can see, ignoring spaces and puntuation, "
			    << "the string is ";
		if(!isPalindrome(s1, s2))
			outfile << "NOT ";
		outfile << "a palindrome.\n-------------------------------------"
			    << endl;

		cout << endl << "Enter some characters and I'll see if it's a palindrome or "
			 << "enter -1 to quit.\n" << endl;
		for(i = 0;(ch = getchar())!='\n'&&i<128;i++)
			data[i] = ch;
		data[i] = '\0';
	}
	outfile.close();
}


bool isOK(char ch)
{
	return (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9');
}

bool isPalindrome(stack<char> &s1, stack<char> &s2)
{
	while(!s1.empty() && !s2.empty())
	{
		if(! (s1.top() == s2.top()))
			return false;
		s1.pop();
		s2.pop();
	}
	return true;
}

The function top() returns a reference to the top element of the stack.

http://www.cppreference.com/cppstack/top.html

It does not return NULL, but returns a reference to the first object in the stack. Checking for NULL is not a valid thing to do.

> outfile << "\n\nThe following string was checked for being a palindrome:"
So why don't you print data (your input array) rather than messing with 20+ lines of stack pushing and popping?

If your argument is that it may have unwanted characters, then consider another function to "clean" the line, since you also do that twice as well.

> void main()
Main returns int, always has done.
It's only sloppy books, compilers and tutors which accept void main.

> assert(!outfile.fail());
This causes the program to bail out in debug mode.
Use if/else to check for filename errors and user input errors.

> for(i = 0;(ch = getchar())!='\n'&&i<128;i++)
Is there any chance of buffer overflow with this code?

> while(strcmp(data, flag) != 0)
To save you having to duplicate the "get input" code, try something like this while ( getUserInput( data ) ) getUserInput is a function which
- prompts for input
- reads a line
- returns the result of the strcmp() result.

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.