Stupid Newbie Needs Help

R

Rich Strang

Hi group I am just starting out in C so please go easy on me :)

I have started to write a small command line interpreter, I have got the
program to break down the commands successfully until I introduce a loop
into the main function. Without the loop the program works fine with the
loop the cout doesn't seem to work, I know I am probably being real stupid
but I would really appreciate some help. Please find the code below:

Thanks Guys

Rich

// **** Rich's Command Line Interpreter ****
// Author: Rich Strang
// Date: 08/10/03

#include <stdio.h>
#include <iostream.h>
#include <ctype.h>

//Set Global
const int iDim1Size=10;
const int iDim2Size=80;


//Function Prototypes:
int GetLine(char[]);
int ParseLine(char[], char[][iDim2Size], int);
int PrintTokens(char[][iDim2Size]);

int main(void)
{
char cInput[iDim2Size];
int iInputSize=0;
char cTokens[iDim1Size][iDim2Size];
int iExit=0;

while(iExit==0)
{
// Prints prompt to screen
printf("$ ");

// Retrieve user input
iInputSize = GetLine(cInput);

if(cInput[0] != 'e' && cInput[1] != 'x' && cInput[2] != 'i' && cInput[3]
!= 't' )
{
// Split user input into tokens
ParseLine(cInput, cTokens, iInputSize);

//Print tokens to screen
PrintTokens(cTokens);
}
else
{
iExit=1;
}
}

return 0;
}

//GetLine Function
int GetLine(char cInput[])
{
int iInputSize=0;
char ch;

for( iInputSize = 0; (iInputSize < 80) && ((ch = getchar()) != EOF) && (ch
!= '\n'); iInputSize++ )
{
cInput[iInputSize] = (char)ch;
}
return iInputSize;
}

//ParseLine Function
int ParseLine(char cInput[], char cTokens[][iDim2Size], int iInputSize)
{
int iIndex=0;
int iA1=0;
int iA2=0;

for( iIndex = 0; (iIndex < iInputSize); iIndex++ )
{
if(cInput[iIndex] != ' ' && cInput[iIndex] != '\t')
{
cTokens[iA1][iA2] = cInput[iIndex];
iA2++;
}
else
{
iA1++;
iA2=0;
}
}
return 0;
}

//Print Tokens Function
int PrintTokens(char cTokens[][iDim2Size])
{
int iIndex1=0;
int iIndex2=0;

for( iIndex1 = 0; (iIndex1 < iDim1Size); iIndex1++ )
{
for( iIndex2 = 0; (iIndex2 < iDim2Size); iIndex2++ )
{
if ( isalpha(cTokens[iIndex1][iIndex2]) ||
isdigit(cTokens[iIndex1][iIndex2]))
{
cout << cTokens[iIndex1][iIndex2];
}
}
cout << "\n";
}

return 0;
}
 
M

Morris Dovey

Rich said:
Hi group I am just starting out in C so please go easy on me :)

Rich...

This group generally goes easy on everyone who writes perfect C
code. The rest of us learn to accept having our mistakes pointed
out in front of the entire world.

You'll need to decide to use either C or C++ (post C++ questions
to In C you'll find that << is the shift
left operator and >> is the shift right operator - and shifting
cout in either direction won't produce the result you're
expecting. There isn't any iostream.h in C.

Rewrite as C and try again.
 
R

Rich Strang

Thanks for your reply, the reason I used << was because I couldn't get
printf to work with the two dimensional array.
 
M

Mike Wahler

Rich Strang said:
Thanks for your reply, the reason I used << was because I couldn't get
printf to work with the two dimensional array.

So show us what you tried that doesn't work, and
we can help you fix it.

-Mike
 
M

Morris Dovey

Rich said:
Thanks for your reply, the reason I used << was because I couldn't get
printf to work with the two dimensional array.

Rich...

It looks like your intent is to send one char at a time to the
standard output.

The easiest way to do this is:

putchar(cTokens[iIndex1][iIndex2]);

but you could also:

fputc(cTokens[iIndex1][iIndex2],stdout);
printf("%c",cTokens[iIndex1][iIndex2]);
fprintf(stdout,"%c",cTokens[iIndex1][iIndex2]);

This is fairly basic stuff. If you don't have a good book to work
with, the link in my sig will lead you to a list of books for
beginners. My suggestion would be "The C Programming Language" by
Kernighan & Ritchie (2nd edition). It's rich and compact - and
you'll use it forever.
 
A

August Derleth

Morris Dovey said:
Rich...

This group generally goes easy on everyone who writes perfect C
code. The rest of us learn to accept having our mistakes pointed
out in front of the entire world.

And, of course, we've all had our mistakes pointed out. Here, that
generally means they'll be fixed. Which is why we come to clc in the
first place, isn't it?
You'll need to decide to use either C or C++ (post C++ questions
to In C you'll find that << is the shift
left operator and >> is the shift right operator - and shifting
cout in either direction won't produce the result you're
expecting. There isn't any iostream.h in C.
[OT]

There isn't an iostream.h in modern C++, either. You should say

#include <iostream>

and preserve the namespaces.

[/OT]
Rewrite as C and try again.

Or, don't, but don't expect us to give you good advice. If the
assignment needs to be in C++, post your code to comp.lang.c++
(preferably after choosing a more descriptive title).
 
J

John Bode

Rich Strang said:
Hi group I am just starting out in C so please go easy on me :)

I'll try. You have a few style issues that I'm going to harp on, but
be aware I rant because I just want to make you a better programmer
(i.e., more like me ;-).
I have started to write a small command line interpreter, I have got the
program to break down the commands successfully until I introduce a loop
into the main function. Without the loop the program works fine with the
loop the cout doesn't seem to work,

Describe exactly what you mean by "doesn't seem to work". FWIW, I
compiled and ran the program below (modulo swapping out the C++ bits
for C) and it worked, mostly (as in, it spat back out what I typed in,
plus a lot of garbage that I didn't enter). You really want to work
with 0-terminated strings, that way you can take advantage of C's
string processing routines.
I know I am probably being real stupid
but I would really appreciate some help. Please find the code below:

Thanks Guys

Rich

// **** Rich's Command Line Interpreter ****
// Author: Rich Strang
// Date: 08/10/03

#include <stdio.h>
#include <iostream.h>
#include <ctype.h>

//Set Global
const int iDim1Size=10;
const int iDim2Size=80;

First style rant: names should be descriptive, meaningful, and
describe usage, *not type*. What, exactly, do iDim1Size and iDim2Size
represent other than array dimensions? What are they to be used for?
It's somewhat clear from the context below that iDim2Size represents
the maximum line length, but I'm not sure how you intend to use
iDim1Size. From the code below it looks like you intend cTokens to
hold up to 10 tokens, where each token may be up to 80 characters
long; is that what you mean? IOW, each input line may contain at most
10 tokens. If that's the case, then maybe iDim1Size should be named
maxTokens or something like that. And instead of iDim2Size, use a
name like lineLength or maxChars or something like that. The name
should give a clue of how the variable/constant/function/macro is
supposed to be used (in a high-level, real-world sense, not in terms
of the specific implementation). I generally frown on Hungarian
notation, at least as it's commonly used. Encoding the type in the
variable name seems like a good idea at first, but what if the base
type of the variable ever has to change?
//Function Prototypes:
int GetLine(char[]);
int ParseLine(char[], char[][iDim2Size], int);
int PrintTokens(char[][iDim2Size]);

int main(void)
{
char cInput[iDim2Size];
int iInputSize=0;
char cTokens[iDim1Size][iDim2Size];
int iExit=0;

while(iExit==0)
{
// Prints prompt to screen
printf("$ ");

fflush (stdout); /* since you aren't printing a newline */
/* you may need to force a flush of the */
/* line buffer to standard output */
// Retrieve user input
iInputSize = GetLine(cInput);

if(cInput[0] != 'e' && cInput[1] != 'x' && cInput[2] != 'i' && cInput[3]
!= 't' )

You might want to reverse the sense of this test (actually, you might
want to work with 0-terminated strings so you can use C's string
library functions like strcmp(), but that's a subject for another
day). C does what's called "short-circuit evaluation" of Boolean
expressions like the above. If you have an expression like "a && b &&
c && d" and a evaluates to false, then the whole expression evaluates
to false regardless of b, c, and d, so they aren't evaluated at all.
So if the first character on your input line is 'e', the above test
will fail, and it won't bother testing against cInput[1], cInput[2],
or cInput[3]. So if you type "evaluate", the loop will still exit.

It might be better to rework this as

if (cInput[0] == 'e' && cInput[1] == 'x' && cInput[2] == 'i' &&
cInput[3] == 't')
{
iExit = 1;
}
else
{
/* parse and print tokens */
}
{
// Split user input into tokens
ParseLine(cInput, cTokens, iInputSize);

//Print tokens to screen
PrintTokens(cTokens);
}
else
{
iExit=1;
}
}

return 0;
}

//GetLine Function
int GetLine(char cInput[])
{
int iInputSize=0;
char ch;

for( iInputSize = 0; (iInputSize < 80) && ((ch = getchar()) != EOF) && (ch
!= '\n'); iInputSize++ )
{
cInput[iInputSize] = (char)ch;
}
return iInputSize;
}

//ParseLine Function
int ParseLine(char cInput[], char cTokens[][iDim2Size], int iInputSize)
{
int iIndex=0;
int iA1=0;
int iA2=0;

for( iIndex = 0; (iIndex < iInputSize); iIndex++ )
{
if(cInput[iIndex] != ' ' && cInput[iIndex] != '\t')
{
cTokens[iA1][iA2] = cInput[iIndex];
iA2++;
}
else
{
iA1++;
iA2=0;
}
}
return 0;
}

//Print Tokens Function
int PrintTokens(char cTokens[][iDim2Size])
{
int iIndex1=0;
int iIndex2=0;

for( iIndex1 = 0; (iIndex1 < iDim1Size); iIndex1++ )
{
for( iIndex2 = 0; (iIndex2 < iDim2Size); iIndex2++ )
{
if ( isalpha(cTokens[iIndex1][iIndex2]) ||
isdigit(cTokens[iIndex1][iIndex2]))
{
cout << cTokens[iIndex1][iIndex2];

putchar (cTokens[iIndex1][iIndex2]);
}
}
cout << "\n";

putchar ('\n');
fflush (stdout);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,104
Messages
2,570,643
Members
47,247
Latest member
youngcoin

Latest Threads

Top