473,320 Members | 1,939 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

STL std::map erase



Hello,

I've got a question conerning erasing key-value pairs from a std::map while
iterating over it.

According to the STL docs, erasing an element in a map invalidates all
iterators pointing to that element

so

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
mymap.erase(i);
mymap.insert(newelement);
}
}

looks like bad practice, and it does crash when it gets executed, at least
on one machine i've run such code on.

So my question is, how do I conveniently erase the "current" element in a
map on the fly while I'm iterating over it? (I admit that this sounds as
weird in English as it sounds in C++)?

Thanx,

Pieter

Jul 22 '05 #1
26 5354
Pieter Thysebaert wrote:

Hello,

I've got a question conerning erasing key-value pairs from a std::map while
iterating over it.

According to the STL docs, erasing an element in a map invalidates all
iterators pointing to that element

so

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
mymap.erase(i);
mymap.insert(newelement);
}
}

looks like bad practice, and it does crash when it gets executed, at least
on one machine i've run such code on.

So my question is, how do I conveniently erase the "current" element in a
map on the fly while I'm iterating over it? (I admit that this sounds as
weird in English as it sounds in C++)?


So what is the real problem?
The problem is, that after erasing the element with iterator i, you need
that iterator again, for the increment, to get at the next map element.
As you know this is not valid. So a possible solution is: get your hands
at an iterator for the next element, *before* you do the erase.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #2

"Pieter Thysebaert" <pi***************@toorug.muchac.spambe> wrote in
message news:c8**********@gaudi2.UGent.be...


Hello,

I've got a question conerning erasing key-value pairs from a std::map while iterating over it.

According to the STL docs, erasing an element in a map invalidates all
iterators pointing to that element

so

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
mymap.erase(i);
mymap.insert(newelement);
}
}

looks like bad practice, and it does crash when it gets executed, at least
on one machine i've run such code on.

So my question is, how do I conveniently erase the "current" element in a
map on the fly while I'm iterating over it? (I admit that this sounds as
weird in English as it sounds in C++)?


for (map<...>::iterator i = mymap.begin(); i != mymap.end(); ) {
if (test(i)) {
mymap.erase(i++);
mymap.insert(newelement);
} else {
++i;
}
}

Understanding this code requires a proper understanding of how 'i++' works.

john
Jul 22 '05 #3

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2ghjh6F2s3b7U1@uni-> >
So my question is, how do I conveniently erase the "current" element in a map on the fly while I'm iterating over it? (I admit that this sounds as
weird in English as it sounds in C++)?


for (map<...>::iterator i = mymap.begin(); i != mymap.end(); ) {
if (test(i)) {
mymap.erase(i++);
mymap.insert(newelement);
} else {
++i;
}
}

Understanding this code requires a proper understanding of how 'i++'

works.

Ok...so how about an explanation?

I don't see how this is any different. When the call to erase finishes, all
iterators pointing to that element are no longer valid. And isn't an
implementation allowed to wait until the erase call returns, and then
perform that increment? In that case, i cannot be incremented because it is
invalid already, right? For such an implementation, incrementing i in the
function parameter ought to be the same as incrementing it in the for
statement, as far as I can see.

Can't an implementation create identical code for both these cases?...

foo(i++);

vs.

f(i);
i++;

I could see that the implementation might not be *required* to make those
the same, but would it not be *allowed* to make them the same?

What am I missing here?

-Howard
Jul 22 '05 #4

"Howard" <al*****@hotmail.com> wrote in message
news:7c*********************@bgtnsc05-news.ops.worldnet.att.net...

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2ghjh6F2s3b7U1@uni-> >
So my question is, how do I conveniently erase the "current" element in
a
map on the fly while I'm iterating over it? (I admit that this sounds
as weird in English as it sounds in C++)?


for (map<...>::iterator i = mymap.begin(); i != mymap.end(); ) {
if (test(i)) {
mymap.erase(i++);
mymap.insert(newelement);
} else {
++i;
}
}

Understanding this code requires a proper understanding of how 'i++'

works.

Ok...so how about an explanation?

I don't see how this is any different. When the call to erase finishes,

all iterators pointing to that element are no longer valid. And isn't an
implementation allowed to wait until the erase call returns, and then
perform that increment?


No, that's exactly the point. i++ is a function call, and that function must
happen before the call to erase. The function call returns the 'old' value
of the iterator (that gets passed to erase), and increments the iterator to
its 'new' value as a side effect. All this must happen before erase is
called.

john
Jul 22 '05 #5

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2g************@uni-berlin.de...

"Howard" <al*****@hotmail.com> wrote in message
news:7c*********************@bgtnsc05-news.ops.worldnet.att.net...

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2ghjh6F2s3b7U1@uni-> >
> So my question is, how do I conveniently erase the "current" element in
a
> map on the fly while I'm iterating over it? (I admit that this
sounds as > weird in English as it sounds in C++)?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); ) {
if (test(i)) {
mymap.erase(i++);
mymap.insert(newelement);
} else {
++i;
}
}

Understanding this code requires a proper understanding of how 'i++' works.

Ok...so how about an explanation?

I don't see how this is any different. When the call to erase finishes,

all
iterators pointing to that element are no longer valid. And isn't an
implementation allowed to wait until the erase call returns, and then
perform that increment?


No, that's exactly the point. i++ is a function call, and that function

must happen before the call to erase. The function call returns the 'old' value
of the iterator (that gets passed to erase), and increments the iterator to its 'new' value as a side effect. All this must happen before erase is
called.

john
Ahah! I understand now. Somehow I keep forgetting that ++ is actually a
function call (operator ++()). Thanks for the explanation.

-Howard

Jul 22 '05 #6
John Harrison wrote:


No, that's exactly the point. i++ is a function call, and that function must
happen before the call to erase.


Ahm.
Thats the wrong explanation.
The correct explanation is:
There is a sequence point immediatly after all arguments
to functions have been evaluated and just before the
function gets called.

So the compiler has no other choice: If there are side
effects during the evaluation of arguments, those side
effects have to be completed before the function gets
called.

That i++ in case of iterators is implemented as a function is
an implementation detail.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #7
Howard wrote:


Ahah! I understand now. Somehow I keep forgetting that ++ is actually a
function call (operator ++()).


It doens't matter.
Even if it were not, the increment has to happen before the
function actually gets called.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #8

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:40***************@gascad.at...
John Harrison wrote:


No, that's exactly the point. i++ is a function call, and that function must happen before the call to erase.


Ahm.
Thats the wrong explanation.
The correct explanation is:
There is a sequence point immediatly after all arguments
to functions have been evaluated and just before the
function gets called.

So the compiler has no other choice: If there are side
effects during the evaluation of arguments, those side
effects have to be completed before the function gets
called.

That i++ in case of iterators is implemented as a function is
an implementation detail.

I wasn't completely sure if the same rules applied to ++ on a built in type,
fairly sure but not completely sure. So I tried to avoid saying 'its because
its a function call' and just gave a descriptive answer.

Thanks for the clarification.

john
Jul 22 '05 #9
John Harrison wrote:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:40***************@gascad.at...
John Harrison wrote:


No, that's exactly the point. i++ is a function call, and that function must happen before the call to erase.


Ahm.
Thats the wrong explanation.
The correct explanation is:
There is a sequence point immediatly after all arguments
to functions have been evaluated and just before the
function gets called.

So the compiler has no other choice: If there are side
effects during the evaluation of arguments, those side
effects have to be completed before the function gets
called.

That i++ in case of iterators is implemented as a function is
an implementation detail.


I wasn't completely sure if the same rules applied to ++ on a built in type,


The ++ has nothing to do with it other then generating a side effect.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #10

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:40***************@gascad.at...
John Harrison wrote:

"Karl Heinz Buchegger" <kb******@gascad.at> wrote in message
news:40***************@gascad.at...
John Harrison wrote:
>
>
> No, that's exactly the point. i++ is a function call, and that
function must
> happen before the call to erase.

Ahm.
Thats the wrong explanation.
The correct explanation is:
There is a sequence point immediatly after all arguments
to functions have been evaluated and just before the
function gets called.

So the compiler has no other choice: If there are side
effects during the evaluation of arguments, those side
effects have to be completed before the function gets
called.

That i++ in case of iterators is implemented as a function is
an implementation detail.

I wasn't completely sure if the same rules applied to ++ on a built in

type,
The ++ has nothing to do with it other then generating a side effect.

--
Karl Heinz Buchegger
kb******@gascad.at

So even if i were an int, it would still have to be incremented prior to
calling the function? That sure seems counter-intuitive to the notion of
"post-increment". Makes sense though, I guess.

Also, I guess that means that what is actually passed to the function is a
*copy* of the original iterator, since the original already has to point to
the next item, right?

This is very enlightening. It seems that I always have more to learn with
this language. Thanks...

-Howard



Jul 22 '05 #11
Howard wrote:
...
So even if i were an int, it would still have to be incremented prior to
calling the function?
Yes.
That sure seems counter-intuitive to the notion of
"post-increment". Makes sense though, I guess.
The function will still receive the original value of 'i'. That's why it
is called "post-increment".
Also, I guess that means that what is actually passed to the function is a
*copy* of the original iterator, since the original already has to point to
the next item, right?


Since this function receives its parameter "by value" - yes, it actually
receives a copy of the original iterator.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #12

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:10*************@news.supernews.com...
Howard wrote:
...
So even if i were an int, it would still have to be incremented prior to
calling the function?


Yes.
That sure seems counter-intuitive to the notion of
"post-increment". Makes sense though, I guess.


The function will still receive the original value of 'i'. That's why it
is called "post-increment".
Also, I guess that means that what is actually passed to the function is a *copy* of the original iterator, since the original already has to point to the next item, right?


Since this function receives its parameter "by value" - yes, it actually
receives a copy of the original iterator.


Ok...but then, what if you were to pass the iterator *by reference* to some
function instead? What value would the function then get, (considering the
previously stated rule that the increment side-effect has to be completed
prior to the calling of the function)? Would a temporary (un-incremented)
copy be created, passed by reference, and then that copy destroyed after the
return of the function? (That seems to be the only way to maintain the
concept of post-increment without violating the side-effect rule.)

-Howard

Jul 22 '05 #13
Howard wrote:
Since this function receives its parameter "by value" - yes, it actually
receives a copy of the original iterator.


Ok...but then, what if you were to pass the iterator *by reference* to
some
function instead? What value would the function then get, (considering
the previously stated rule that the increment side-effect has to be
completed
prior to the calling of the function)? Would a temporary (un-incremented)
copy be created, passed by reference, and then that copy destroyed after
the
return of the function? (That seems to be the only way to maintain the
concept of post-increment without violating the side-effect rule.)


That depends on how the iterator implements the pre and post ++ operators.
Habitually the post version returns a copy of the old value.

--
Salu2
Jul 22 '05 #14
Pieter Thysebaert wrote:

Hello, According to the STL docs, erasing an element in a map invalidates all
iterators pointing to that element

so

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
mymap.erase(i);
mymap.insert(newelement);
}
}


Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}


Jul 22 '05 #15
joey tribbiani wrote:

Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}


Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #16

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
joey tribbiani wrote:

Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}


Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.


Even with this extension/future std, the above is incorrect. 'i' will be
effectively incremented twice for each true 'test(i)'. 'i++' needs to be
moved from the for statement to an else clause.

Jeff F
Jul 22 '05 #17
Pete Becker wrote:
joey tribbiani wrote:
Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}

Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.

Oh, thanks, i didn't know - always thought you are the standard
(actually, never really thought about it)
Jul 22 '05 #18

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
joey tribbiani wrote:

Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}


Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.


Even if it *did* return an iterator, the above code would only work if it
returned an iterator to the *previous* item, because the for loop is going
to increment i every time. The implementation I'm using returns an iterator
to the *next* item (or to end(), if there are none beyond the given item).
In that case, it would have to be writtien:

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); )
{
if (test(i))
i = mymap.erase(i);
else
i++;
}

-Howard
Jul 22 '05 #19
Jeff Flinn wrote:

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
joey tribbiani wrote:

Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}


Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.


Even with this extension/future std, the above is incorrect. 'i' will be
effectively incremented twice for each true 'test(i)'. 'i++' needs to be
moved from the for statement to an else clause.


So tell the person who posted it.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #20
Howard wrote:

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
joey tribbiani wrote:

Why not the following?

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
i = mymap.erase(i);
}
}


Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.


Even if it *did* return an iterator, the above code would only work if it


So tell the person who posted it.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #21

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
Jeff Flinn wrote:

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
joey tribbiani wrote:
>
> Why not the following?
>
> for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
> if (test(i)) {
> i = mymap.erase(i);
> }
> }

Because map::erase returns void according to the standard. Our
implementation returns an iterator, just like vector::erase. The next
version of the standard will probably make that change official.


Even with this extension/future std, the above is incorrect. 'i' will be
effectively incremented twice for each true 'test(i)'. 'i++' needs to be
moved from the for statement to an else clause.


So tell the person who posted it.


Assuming this thread is important to the OP, I just did. ;)

I'm also telling someone googling down this thread a few years hence, when
the T::iterator is the standard, that this needs to be corrected.

Jeff F
Jul 22 '05 #22
Jeff Flinn wrote:
So tell the person who posted it.


Assuming this thread is important to the OP, I just did. ;)


Sigh. Okay. RESPOND TO THE PERSON WHO ORIGINALLY POSTED THE WORDS THAT
YOU THINK ARE INCORRECT. Is it really that hard to grasp?

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #23

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
Jeff Flinn wrote:
So tell the person who posted it.


Assuming this thread is important to the OP, I just did. ;)


Sigh. Okay. RESPOND TO THE PERSON WHO ORIGINALLY POSTED THE WORDS THAT
YOU THINK ARE INCORRECT. Is it really that hard to grasp?

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)


Why are you so upset??? So our responses fall under yours instead of
directly under joey's. So what? He should be perfectly capable of seeing
the whole conversation, and the context of the responses. (Aren't you?)
It's not like we sent emails to you personally. We posted them to the
newsgroup, as follow-ups to your response. There's no sense in now going
back and posting *again*, directly to joey's post, just so he (and everyone
else) can read the same answer for the third time. Relax a little. We're
not attacking you, just posting follow-up info to the conversation.

-Howard


Jul 22 '05 #24
Howard wrote:

"Pete Becker" <pe********@acm.org> wrote in message
news:40***************@acm.org...
Jeff Flinn wrote:

> So tell the person who posted it.

Assuming this thread is important to the OP, I just did. ;)

Sigh. Okay. RESPOND TO THE PERSON WHO ORIGINALLY POSTED THE WORDS THAT
YOU THINK ARE INCORRECT. Is it really that hard to grasp?

Why are you so upset??? So our responses fall under yours instead of
directly under joey's. So what?


So you confuse things when you respond to the wrong message. I really
don't see why that's so hard to grasp.
He should be perfectly capable of seeing
the whole conversation, and the context of the responses. (Aren't you?)
It's not like we sent emails to you personally. We posted them to the
newsgroup, as follow-ups to your response. There's no sense in now going
back and posting *again*, directly to joey's post, just so he (and everyone
else) can read the same answer for the third time.


Sigh. Nobody suggested posting *again*.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #25
Howard wrote:
...
Since this function receives its parameter "by value" - yes, it actually
receives a copy of the original iterator.


Ok...but then, what if you were to pass the iterator *by reference* to some
function instead? What value would the function then get, (considering the
previously stated rule that the increment side-effect has to be completed
prior to the calling of the function)? Would a temporary (un-incremented)
copy be created, passed by reference, and then that copy destroyed after the
return of the function? (That seems to be the only way to maintain the
concept of post-increment without violating the side-effect rule.)


Yes, that's pretty much correct. Note that if you make an attempt to
pass it by non-constant reference, the code simply won't compile,
because post-increment normally returns an rvalue and non-constant
reference cannot be bound to an rvalue. But if the function is declared
with constant reference parameter, then everything will work as you
describe, i.e. the reference will be bound to a temporary object, which
holds the original (un-incremented) value.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #26

"Pieter Thysebaert" <pi***************@toorug.muchac.spambe> wrote in message news:c8**********@gaudi2.UGent.be...


Hello,

I've got a question conerning erasing key-value pairs from a std::map while
iterating over it.

According to the STL docs, erasing an element in a map invalidates all
iterators pointing to that element

so

for (map<...>::iterator i = mymap.begin(); i != mymap.end(); i++) {
if (test(i)) {
mymap.erase(i);
mymap.insert(newelement);
}
}

looks like bad practice, and it does crash when it gets executed, at least
on one machine i've run such code on.

So my question is, how do I conveniently erase the "current" element in a
map on the fly while I'm iterating over it? (I admit that this sounds as
weird in English as it sounds in C++)?

Thanx,

Pieter


I've run into that situation many times with maps, lists and other containers,
and the easiest solution, I've found, is to get a copy of i called j, decrement i,
then erase (*j). Like so:

map<K, V> mymap; // where K and V are types
map<K, V>::iterator i, j; // get some iterators
for (i = mymap.begin(); i != mymap.end(); i++)
{
if (test(i))
{
j = i; // get temp. copy of i
--i; // gonna kill place where i pointed, so back up!
mymap.erase(j); // erase element where i used to point
mymap.insert(newelement); // automatically sorted; where did it go?
}
}

If i was decremented and (*j) erased, then when execution resumes at the
top of the loop, i will be incremented to the next un-erased item.

Also be aware that there's no guarantee the inserted item went the same
place as the deleted one; map is automatically sorted by key, so the new
element could end up anywhere, depending on sort order.
--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant

----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Jul 22 '05 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Angus Leeming | last post by:
Dinkumware's online STL reference http://tinyurl.com/3es52 declares std::map's overloaded erase member functions to have the interface: map::erase iterator erase(iterator where); iterator...
8
by: Michael Klatt | last post by:
I need an efficient insert-or-replace algorithm based on the key_type of a std::map. The user needs to be notified if a replacement occurs. This is what I have: class Key; typedef map<Key,...
1
by: Saeed Amrollahi | last post by:
Dear All C++ Programmers Hello I am Saeed Amrollahi. I am a software engineer in Tehran Sewerage Company. I try to use std::map and map::find member function. I use Visual Studio .NET. my...
8
by: Kelly Mandrake | last post by:
I have been learning about STL's map class. I see that I can clear a hashmap by useing the method clear, however I decided to try to clear the hash with a for loop. Since erase can take an...
17
by: Gernot Frisch | last post by:
restart: for (std::map<x,y>::iterator it = m.begin(); it!=m.end(); ++it) { if( it->second.isbad() ) { std::map<x,y>::iterator next = it; ++next; m.erase(it); it=next; // goto restart;
3
by: Dan Trowbridge | last post by:
Hi everyone, In my attempt to port code from VS 6.0 to VS.NET I had some code break along the way, mostly due to not adhereing closely to the C++ standard. This may be another instance but I...
13
by: kamaraj80 | last post by:
Hi I am using the std:: map as following. typedef struct _SeatRowCols { long nSeatRow; unsigned char ucSeatLetter; }SeatRowCols; typedef struct _NetData
20
by: Dilip | last post by:
I understand the C++ standard does not talk about threading. My question here is directed more towards what happens when a STL container is used in a certain way. I'd appreciate any thoughts. I...
2
by: digz | last post by:
Hi, I am trying to write a program which has two threads one of them write to a map , and the other one deletes entries based on a certain criterion.. first I cannot get the delete portion to...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.