sth wrong?

H

Hello

i'm trying to make a program to take out non alpha characters from
entered text...but 'ntext' is always 4 char larger than the size
j...why is that?
any better ways to do this? thanks lots people.

void main()
{

int i, j=0;
char text[9999];
char *ntext;
gets(text);
for (i=0; text; i++){
if(isalpha(text))
j++;
}
ntext=new char [j];
cout<<j<<" "<<strlen(ntext);
for (i=0, j=0; text;i++){
if (isalpha(text)){
ntext[j]=text;
j++;
}
}
strcpy(text, ntext);
cout<<endl;
for (i=0; text; i++)
cout<<endl<<text;
delete [] ntext;


}
 
K

Karthik Kumar

Hello said:
i'm trying to make a program to take out non alpha characters from
entered text...but 'ntext' is always 4 char larger than the size
j...why is that?
any better ways to do this? thanks lots people.

This can be definitely done better.
void main()
{

int i, j=0;
char text[9999];

string text;

char *ntext;
gets(text);

use getline method of istream ( cin ).

There had been so many buffer overflows
thanks to gets. Do not use it.
for (i=0; text; i++){
if(isalpha(text))
j++;
}
ntext=new char [j];


Ok - you are allocating a chunk of memory
afresh.
cout<<j<<" "<<strlen(ntext);

And right away, you are trying to find
the length of the string.
Considering this as a C program,
this is still bad. where are you
setting the null character (that is the
delimeter that strlen looks for ).

for (i=0, j=0; text;i++){
if (isalpha(text)){
ntext[j]=text;
j++;
}
}
strcpy(text, ntext);


The problem remains the same.
You are not setting the null character
for ntext. and you are trying to copy
from ntext.

Consider using C++ strings. You won't
have all these troubles.
 
D

Dietmar Kuehl

Hello said:
void main()

There is no such thing as 'void main()'! Any compiler accepting
this code without a diagnostic is in error.
gets(text);

You shall *NEVER* use 'gets()'! It is the primary source for
security problems. The issue is that you cannot guarantee that
the array you give to 'gets()' is sufficiently large. Use
'fgets()' or, even better, 'std::getline()' instead (the member
function 'getline()' has a similar problem although it is
possible to setup a maximum width: it is just easy to forget
and thus this member function is error prone).
ntext=new char [j];

This is at least one character too small: you need space for a
terminating null character.
cout<<j<<" "<<strlen(ntext);
for (i=0, j=0; text;i++){
if (isalpha(text)){
ntext[j]=text;
j++;
}
}


.... and, of course, you need to add the terminating null
character before copying the new string somewhere:
strcpy(text, ntext);

You might want to investigate the class 'std::string' and the
algorithm 'std::remove()'. Here is the moral equivalent of your
code using C++:

| #include <iostream>
| #include <string>
| #include <algorithm>
| #include <ctype.h>
|
| bool notalpha(char c)
| {
| return !std::isalpha(static_cast<unsigned char>(c));
| }
|
| int main()
| {
| for (std::string line; std::getline(std::cin, line); )
| {
| std::string tmp(line);
| tmp.erase(std::remove_if(tmp.begin(), tmp.end(), notalpha),
| tmp.end());
| std::cout << tmp << "\n";
| }
| }
 
M

Mike Wahler

Dietmar Kuehl said:
| #include <iostream>
| #include <string>
| #include <algorithm>
| #include <ctype.h>
|
| bool notalpha(char c)
| {
| return !std::isalpha(static_cast<unsigned char>(c));
| }
|
| int main()
| {
| for (std::string line; std::getline(std::cin, line); )
| {
| std::string tmp(line);
| tmp.erase(std::remove_if(tmp.begin(), tmp.end(), notalpha),
| tmp.end());
| std::cout << tmp << "\n";
| }
| }

Will google post that correctly if you change the '|'
to /**/ ? Then we could copy/paste and compile.

-Mike
 
W

White Wolf

Mike said:
Will google post that correctly if you change the '|'
to /**/ ? Then we could copy/paste and compile.

Or he could post it compiled, and the we would only need to run it. ;-)
 
D

Default User

Mike said:
Will google post that correctly if you change the '|'
to /**/ ? Then we could copy/paste and compile.


Let's give 'er a whirl:


/**/ int main()
/**/ {
/**/ for (std::string line; std::getline(std::cin, line); )
/**/ {
/**/ std::string tmp(line);
/**/ tmp.erase(std::remove_if(tmp.begin(), tmp.end(), notalpha),
/**/ tmp.end());
/**/ std::cout << tmp << "\n";
/**/ }
/**/ }

Looks ok in the Preview, so it should be good for you.



Brian
 
M

Mike Wahler

Default User said:
Let's give 'er a whirl:


/**/ int main()
/**/ {
/**/ for (std::string line; std::getline(std::cin, line); )
/**/ {
/**/ std::string tmp(line);
/**/ tmp.erase(std::remove_if(tmp.begin(), tmp.end(), notalpha),
/**/ tmp.end());
/**/ std::cout << tmp << "\n";
/**/ }
/**/ }

Looks ok in the Preview, so it should be good for you.

Looks good here (OE6 in 'text mode'). Thanks for taking
the time.

I officially propose this as our new 'google defense'.

Now if I can figure out how to automate that in my
editor. :)

-Mike
 
J

Jerry Coffin

i'm trying to make a program to take out non alpha characters from
entered text...but 'ntext' is always 4 char larger than the size
j...why is that?
any better ways to do this? thanks lots people.

In this case, I think C is as effective as C++:

int main() {
int ch;
while (EOF!=(ch=getchar()))
if (isalpha(ch)
putchar(ch);
return 0;
}

If you really want to use things specific to C++, you have a fair
number of choices though. Just for one exzample:

// Minimally tested
#include <iostream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <ios>

int main() {
std::noskipws(std::cin);
std::remove_copy_if(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
std::eek:stream_iterator<char>(std::cout),
std::isalpha);
return 0;
}

I have a new ambition in life: to be able to write a program that
consists entirely of #include's, with no actual code at all. :)
 
H

Howard

Default User said:
Let's give 'er a whirl:


/**/ int main()
/**/ {
/**/ for (std::string line; std::getline(std::cin, line); )
/**/ {
/**/ std::string tmp(line);
/**/ tmp.erase(std::remove_if(tmp.begin(), tmp.end(), notalpha),
/**/ tmp.end());
/**/ std::cout << tmp << "\n";
/**/ }
/**/ }

Looks ok in the Preview, so it should be good for you.



Brian

Unless, of coure, you include multi-line comments in your code. :-0

-H
 
W

White Wolf

Mike Wahler wrote:
[SNIP]
Now if I can figure out how to automate that in my
editor. :)

Change start of line to /**/ in regexp search and replace. If your editor
does not know this throw it away, and start using NEdit (assuming some *nix
environment). ;-)
 
J

Jerry Coffin

[ ... ]

// Minimally tested
#include <iostream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <ios>


int main() {
std::noskipws(std::cin);
std::remove_copy_if(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
std::eek:stream_iterator<char>(std::cout),
std::isalpha);
return 0;
}

Perhaps I should have said "minimally, but totally incorrectly tested"
-- I managed to get the C version correct, but in the C++ version I got
the sense wrong -- instead of using isalpha directly, we need to use a
function to invert its sense (and, unfortunately, std::not1 won't
work). e.g.:

bool notalpha(char ch) {
return !std::isalpha((unsigned char)ch);
}

// ...
std::remove_copy_if( /* ... */
notalpha);

Sorry 'bout that...

--

Later,
Jerry.

The universe is a figment of its own imagination.
 
M

Mike Wahler

White Wolf said:
Mike Wahler wrote:
[SNIP]
Now if I can figure out how to automate that in my
editor. :)

First of all, that remark was meant 'tongue-in-cheek', as
I don't post with google (shudder).
Change start of line to /**/ in regexp search and replace. If your editor
does not know this throw it away, and start using NEdit (assuming some *nix
environment). ;-)

I wasn't thinking of an 'after the fact' fix, but a feature
that automatically added predefined text to each line as
I type, without any intervention on my part, like the old
MS-DOS editor 'BRIEF' (btw still my all time favorite editor)
could do.

-Mike
 
W

White Wolf

Mike Wahler wrote:
[SNIP]
I wasn't thinking of an 'after the fact' fix, but a feature
that automatically added predefined text to each line as
I type, without any intervention on my part, like the old
MS-DOS editor 'BRIEF' (btw still my all time favorite editor)
could do.

I guess NEdit can do that too. My favoriute was MultiEdit and something
called E!, which was a kind of programmable vi clone. The MultiEdit we had
(in DOS) was a beast which was completely programmed in its own macro
language. I mean the user interface, the menus and all.
 
M

Mike Wahler

White Wolf said:
Mike Wahler wrote:
[SNIP]
I wasn't thinking of an 'after the fact' fix, but a feature
that automatically added predefined text to each line as
I type, without any intervention on my part, like the old
MS-DOS editor 'BRIEF' (btw still my all time favorite editor)
could do.

I guess NEdit can do that too. My favoriute was MultiEdit and something
called E!, which was a kind of programmable vi clone. The MultiEdit we had
(in DOS) was a beast which was completely programmed in its own macro
language. I mean the user interface, the menus and all.

Sounds very similar to BRIEF. (I seem to recall the name is
an acronym: Basic Reconfigurable Interactive Editing Facility
-- now *that's* a mouthful! :))

-Mike
 

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

Members online

Forum statistics

Threads
474,199
Messages
2,571,045
Members
47,643
Latest member
ashutoshjha_1101

Latest Threads

Top