This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I've been going through the go tour, and I've finished the web crawler exercise, but I think that the technique I used to print all the results may be inefficient.
Here is my code. I only edited the crawl and main functions so I'll just post that. Here is the link to the exercise ( http://tour.golang.org/#70 )
var used = make(map[string]bool)
func Crawl(url string, depth int, fetcher Fetcher, results chan string) {
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
results <- fmt.Sprintf("%v",err)
return
}
results <-fmt.Sprintf("\nfound: %s %q\n", url, body)
for _,u := range urls {
if used[u] == false {
used[u] = true
go Crawl(u, depth-1, fetcher, results)
}
}
return
}
//------------------------------------------------------------
func main() {
used["http://golang.org/"] = true
results := make(chan string)
go Crawl("http://golang.org/", 4, fetcher, results)
for i := 0; i < len(used); i++ {
fmt.Println(<-results)
}
}
I use the "for i < len(used)" line in main to ensure that the value from results is printed only if there is a result to print. I can't just use
for i := range results
because it is hard to use "close(results)" in the crawl function since it is recursive, but with the way I do it I have to find the length of the variable used every time.
Is there a better way to do this?
To wait for a collection of goroutines to finish, use a sync.WaitGroup.
I believe you'll find the example in the official documentation very familiar..
http://golang.org/pkg/sync/#example_WaitGroup
Quoting:
var wg sync.WaitGroup
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.somestupidname.com/",
}
for _, url := range urls {
// Increment the WaitGroup counter.
wg.Add(1)
// Launch a goroutine to fetch the URL.
go func(url string) {
// Fetch the URL.
http.Get(url)
// Decrement the counter.
wg.Done()
}(url)
}
// Wait for all HTTP fetches to complete.
wg.Wait()
This will block until all the work is done.
If you really want to print the results progressively as you collect them, the simplest way is to do it in the fetcher itself.
Related
The Go tour shows an example where they have an extra statement in the same line as the "if" statement and they explain it like this: the if statement can start with a short statement to execute before the condition.
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
I don't see the need for this syntax and find it very confusing. Why not just write v := math.Pow(x, n) in the previous line?
The reason I'm asking is that for what I'm finding out, syntax finds its way into the Go language after careful consideration and nothing seems to be there out of whim.
I guess my actual question would be: What specific problem are they trying to solve by using this syntax? What do you gain by using it that you didn't have before?
There are many use cases and I do not think this feature tackles a specific problem but is rather a pragmatic solution for some problems you encounter when you code in Go. The basic intentions behind the syntax are:
proper scoping: Give a variable only the scope that it needs to have
proper semantics: Make it clear that a variable only belongs to a specific conditional part of the code
Some examples that I remember off the top of my head:
Limited scopes:
if v := computeStuff(); v == expectedResult {
return v
} else {
// v is valid here as well
}
// carry on without bothering about v
Error checking:
if perr, ok := err.(*os.PathError); ok {
// handle path error specifically
}
or more general, Type checking:
if someStruct, ok := someInterface.(*SomeStruct); ok {
// someInterface is actually a *SomeStruct.
}
Key checking in maps:
if _, ok := myMap[someKey]; ok {
// key exists
}
Because so your variables are contained in the scope
Notice that those v are declared on different scope.
A more direct example to understand scopes: http://play.golang.org/p/fInnIkG5EH
package main
import (
"fmt"
)
func main() {
var hello = "Hello"
{
hello := "This is another one"
fmt.Println(hello)
}
if hello := "New Hello"; hello != ""{
fmt.Println(hello)
}
fmt.Println(hello)
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
i have corrected the errors in the program below, but am still getting mixed output. the updated results are below. Please advise.
I would appreciate any help. The relevant code sections are:
string student::standing() const
// post: use selection to return the current standing as either
// Freshman, Sophomore, Junior, or Senior.
{
cout << "Freshman";
if (my_credits <= 60.00);
{cout << "Sophomore";}
if (my_credits <= 90.00);
{cout << "Junior";}
if (my_credits >= 90.00);
else
{ cout << "Senior";}
}
string student::name() const
// post: return the student's name
{
{return my_name;}
}
Uhm, first of all your title references one error and your question shows another. Both are legitimate so let's fix both, shall we?
The thing is the C4716 error message tells you exactly what the error is: you just have to read it. It says that the function student::standing() claims to return a string but doesn't. Of course, that's not the only issue. The other problem, which you claim is C2134 (but is likely C4390) is caused because you you put a semicolon after you if which isn't right. This code:
if(my_credits <= 60.00);
{cout << "Sophomore";}
is the same as this code:
if(my_credits <= 60.00)
/* do nothing if my_credits are less than or equal to 60 */
{
/* and then always print "Sophomore" */
cout << "Sophomore";
}
Chances are that what you really want is this:
string student::standing() const
{
if(my_credits >= 90.00)
return "Senior";
if(my_credits >= 60.00)
return "Junior";
if(my_credits >= 30.00)
return "Junior";
return "Freshman";
}
For future reference, if you had searched on Google for C4390, you would have landed on an MSDN page describing this error which includes an exact description of the issue, along with the very mistake you made.
Similarly, if you had Googled for C4716, you would have landed on another MSDN page describing that error which again includes an example that's very close to what your mistake.
Finally, in this code:
string student::name() const
{
{return my_name;}
}
What is the point in those extra curly braces? They don't really hurt anything, but they just serve no conceivable purpose, except to confuse. Remove them:
string student::name() const
{
return my_name;
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
In Windows, one can use structured exception handling in C to write a pseudo-loop that prints all numbers from 1 to 1000 like this:
int n = 0;
__try {
*(int *)0 = 0;
}
__except(printf("%i\n", ++n), n < 1000 ? -1 : 1) {
}
I wonder if there are also other ways in C/C++ to create a loop that isn't trivial to detect if you search the code for the usual suspect keywords for, while and goto.
In C++, a simple lambda can do that:
std::function<void(int,int)> print = [&](int from, int to)
{
std::cout << from << " ";
if ( from < to ) print(++from, to);
};
print(1, 1000);
It will print all integers from 1 to 1000. And it doesn't use for, while or goto.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Relevant code is as follows:
I've tested each Nurse object assignment and the entire thing separately and the data is stored correctly, I'm just not able to access it to determine which tiles to display for some reason. I've also tried accessing the data without an iterator and that didn't work either. Any ideas are thoroughly appreciated, I've been trying to figure this out for hours :/
for(unsigned int j = 42; j < EntityManager::getInstance()->nurses.size() * 42 + 42; j += 42) //increment y axis
{
int rosterCounter = 0;
int count = 0;
vector<string> roster = EntityManager::getInstance()->nurses[count]->getRosterData();
vector<string>::const_iterator iter;
iter = roster.begin();
for(unsigned int i = GraphicsCore::getInstance()->screenWidth; rosterCounter <= EntityManager::getInstance()->getSize() && iter != roster.end(); i -= 64) //iterate through each column, RTL
{
TextBox * text;
if(*iter == "D")
{
text = new TextBox("resources/tiles/textboxshortd.png", i, j, (TextBox::type) 4);
}
else if(*iter == "N")
{
text = new TextBox("resources/tiles/textboxshortn.png", i, j, (TextBox::type) 4);
}
else if(*iter == "O")
{
text = new TextBox("resources/tiles/textboxshorto.png", i, j, (TextBox::type) 4);
}
else
{
text = new TextBox("resources/tiles/textboxshort.png", i, j, (TextBox::type) 4);
}
iter++;
rosterCounter++;
}
count++;
}
Edit: It now runs but the first iteration seems to do nothing, no tiles are placed at all in the first column for some reason and it appears to be offset entirely by 1. I tried begin()-1 but that didn't work either. Thanks for your help guys :)
You're never checking your iterator to see whether it's != roster.end(). If it is, it will lead to undefined behavior when you attempt to dereference or increment it.
Also, note that your code most likely leaks. You never delete text;.
if you know the size of it
vector.size()
you can access each element by
vector.at(x);
If the Entity Manager gives you a copy of the data than this should be ok (i assume it because its not a pointer)
What you maybe have to explain is why you have such cryptic for loops it makes no sense that your first loop starts with 42 in the index variable, i think you are doing two things in one step and that makes your life more difficult.
As you might know you should provide the line it crashes on.
If you first pick the data and after display it, you would probably spot the error by yourself.
Edit: I have realized that you seem not to understand what you are doing, don't just hack around in your code, visualize your problem. In addition, your logic is not clear to me, when you have a vector with 10 elements, why would you try to access element -1 if element 0 will not print out the value you want to see? You should try it the other way around, check why the value at 0 is not containing what you want. I also assume that you haven't written the initial code, try to understand the code first. Get some paper and draw the current work flow and the targeted work flow you are trying to build.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am using C++ string functions in cocos2dx. I have the following string CorrectAns = "below".
for(int i = 0; i<CorrectAns.size();i++)
{
CorrectAns.replace(i,i,"?");
}
This function should return my string as "?????", but its returning only 4 charcters ie "????".
When I write like this,
for(int i = 0; i<CorrectAns.size();i++)
{
if(i == 0)
{
CorrectAns.replace(i,i,"?");
}
}
It just crashes.
and works fine only when I write it as " CorrectAns.replace(i,i+1,"?");"
Why is the function working this way?? Can anyone help me please??
string& replace ( size_t pos1, size_t n1, const string& str );
For the versions with parameters pos1 and n1, the section replaced
begins at character position pos1 and spans for n1 characters within
the string.
So you should use
for(int i = 0; i<CorrectAns.size();i++)
{
CorrectAns.replace(i,1,"?");
}
Mb it will be more usefull use something like
CorrectAns.assign(CorrectAns.size(), '?');