-
Help with C simple loop.
Hey guys, I am trying to write a loop that will iterate through a char array in C and pull the IP addresses and test them to see if hthey respond. My ultimate goal is to have the first one that responds returned in the function, but the loop is not running correctly. It will run through right the first time, but then will start over again. Any help would be greatly appreciated. Thanks.
Code:
const char * getServer(char *svrList)
{
char *srList;
srList = strtok(svrList, " ," );
printf("Contents of srList b4 loop: %s\n", srList);
printf("Server List: %s\n", svrList);
while(srList !=NULL)
{
printf("result is \"%s\"\n", srList);
char pComm[512];
memset(pComm, '\0', sizeof(512));
sprintf(pComm, "ping -c 1 %s > /dev/null", srList);
if((system (pComm))==0)
{
printf("result is \"%s\"\n", srList);
return "%s", srList;
}
else
{
printf("Hitting else loop\n");
printf("Contents of srList in else: %s\n", srList);
}
srList = strtok(NULL, " ," );
}
return "0";
}
char svrList[] = "1.1.1.1, 2.2.2.2, 4.2.2.2, 8.8.8.8";
getServer(svrList)
Quote:
Code output:
Contents of srList b4 loop: 1.1.1.1
Server List: 1.1.1.1
result is "1.1.1.1"
Hitting else loop
Contents of srList in else: 2.2.2.2
result is "2.2.2.2"
result is "2.2.2.2"
Contents of srList b4 loop: 1.1.1.1
Server List: 1.1.1.1
result is "1.1.1.1"
Hitting else loop
Contents of srList in else: (null)
-
Re: Help with C simple loop.
Code:
memset(pComm, '\0', sizeof(512));
What does this line do?
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Code:
return "%s", srList;
What is this supposed to do?
The point being -- neither of the lines that I posted do what you think they do.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Quote:
Originally Posted by
Paul McKenzie
Code:
return "%s", srList;
What is this supposed to do?
The point being -- neither of the lines that I posted do what you think they do.
Regards,
Paul McKenzie
I thought I would need this to return the first value in srList that succeeds. Is that not the case? As far as the memset function, I thought I needed this as part of iterating through the array.
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
I thought I would need this to return the first value in srList that succeeds. Is that not the case?
No. You can return only one value. I don't know where you could have gotten the information that a return statement can do all of the things you stated it can do. What you posted was usage of the comma operator, and that is what trips up a lot of people who erroneously write code that has commas.
Quote:
As far as the memset function, I thought I needed this as part of iterating through the array.
Do you know what each of those parameters in memset() does? To the point, what does the third parameter denote? What is the value of sizeof(512)?
http://www.cplusplus.com/reference/cstring/memset/
Code:
#include <stdio.h>
int main()
{
printf("The sizeof(512) is %d", sizeof(512));
}
What gets printed?
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Well, ideally, I was trying to return just the first address that responds and then quit the function with a return value for the IP of the server that succeeded. If it didn't, then continue the loop until all items in array are exhausted, then return "0" so that it will fail in the rest of the code. I got it to return correctly if the first IP address in the array is responding, but for some reason after it goes past the first one on a failure, it messes it all up. From what I can tell the memset will fill the char array of pComm with 0's. Not sure if that is correct.
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
Well, ideally, I was trying to return just the first address that responds and then quit the function with a return value for the IP of the server that succeeded. If it didn't, then continue the loop until all items in array are exhausted, then return "0" so that it will fail in the rest of the code. I got it to return correctly if the first IP address in the array is responding, but for some reason after it goes past the first one on a failure, it messes it all up.
You need to review the syntax of the return statement, and not guess what it does. Then write the code properly.
The return statement is simple -- it returns a single value back to the caller, nothing else.
Quote:
From what I can tell the memset will fill the char array of pComm with 0's. Not sure if that is correct.
Again, the third parameter is the one that is in question. It is highly important that you know what it means. That parameter tells memset() the number of bytes to set, and sizeof(512) is equal to 4 on my compiler. Do you really only want to set 4 bytes?
You can't write a C or C++ program by guessing what various functions do, and guessing what a particular syntax is supposed to do. The reason is that it is very easy to write totally incorrect code, thinking that the code is doing its job for you. One such case is yours, and that is erroneously using the comma operator without knowing that you're using it.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Also, let's say you really wanted to do this:
Since srList is a pointer to a local variable, returning a pointer to a local variable is undefined behaviour. That program could have crashed as soon as you attempt to use that returned value.
Edit: I see that you're setting it to strtok() return value, which is pointing to the string you supplied the function. So you're OK for now.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Also, your program is not a C program. It is a C++ program that you believe is a C program. I know this, because of these lines of code:
Code:
printf("result is \"%s\"\n", srList);
char pComm[512];
In C, you cannot declare a variable after an executable statement. That statement must come first in the functional block. Only in C++ could you declare a char array at that location.
So why are you writing C when you're obviously using a C++ compiler? If you wrote the function in C++ using std::string, then this becomes much easier.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
OK, so in looking at the memset function again, according to this website, it would fill the array with 0's like I said, so I am stumped.http://www.elook.org/programming/c/memset.html I don't think I really NEED that memset to fix this loop, but I have looked into the return and from what I can tell, I should just reformat the return to be "return (srList);". Since you said I can only return once, if I take out the return "0", then how would I return a "0" if the loop does not contain an IP that passes the first part of the loop in the IF statement?
-
Re: Help with C simple loop.
Quote:
Originally Posted by
Paul McKenzie
Also, your program is not a C program. It is a C++ program that you believe is a C program. I know this, because of these lines of code:
Code:
printf("result is \"%s\"\n", srList);
char pComm[512];
In C, you cannot declare a variable after an executable statement. That statement must come first in the functional block. Only in C++ could you declare a char array at that location.
So why are you writing C when you're obviously using a C++ compiler? If you wrote the function in C++ using std::string, then this becomes much easier.
Regards,
Paul McKenzie
This compiles with gcc, so I am not sure why it is letting me do it.
-
Re: Help with C simple loop.
Another thing -- are you using the debugger that comes with your compiler to see where things break down? If you did that, then there is little need to clutter your code with printf() statements.
First problem:
Code:
const char * getServer(char *svrList)
{
char *srList;
srList = strtok(svrList, " ," );
printf("Contents of srList b4 loop: %s\n", srList);
What if srList is NULL? Your "debugging" printf() would go haywire, since it is undefined as to what will happen if you give "%s" in printf() a NULL pointer. So with that one line of code, you've potentially killed your function. That's why you should use the debugger.
Code:
char pComm[512];
memset(pComm, '\0', sizeof(512));
This should be
Code:
char pComm[512];
memset(pComm, '\0', sizeof(pComm));
Next:
Code:
return "%s", srList;
The only thing returned here is srList, all of the result of the comma operator.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
OK, so in looking at the memset function again, according to this website, it would fill the array with 0's like I said, so I am stumped.
Did you read what each parameter does? What does the third parameter denote?
When you call a function, you're supposed to not only know what the function does, but make sure you know what each parameter is supposed to denote. You're stuck on what the function does, and I'm trying to get you to read the docs on what each parameter does. If you did that, you should see that the last parameter that you provided to memset() is not correct:
Quote:
num
Number of bytes to be set to the value.
size_t is an unsigned integral type.
The array is 512 bytes, but you're telling memset() to set sizeof(512) bytes, which is equal to 4.
Quote:
Since you said I can only return once,
No. What I stated is that you can only return one value. You can have a thousand return statements, but each one only returns one value.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
This compiles with gcc, so I am not sure why it is letting me do it.
You need to know if you are compiling a C++ program. If you are, then the syntax is valid. If not, then I don't know if this is one of gcc's "extensions", or if it is something in C99 (I don't use C99) that makes it compile.
One way to know for sure is to include a C++ header such as <string> and see if the code still compiles. If it still compiles, then you're compiling a C++ program and not a C program.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
OK, I am sorry, I see what you are saying. I am in the process of debugging, but since I am in windows, I cannot find a good debugger that will work well. I have visual studio, but it does not include all the classes that I am using in my program and from what I read it is not recommended to add them. Any suggestions on this?
-
Re: Help with C simple loop.
Another important point if this is really a 'C' program:
You should post a full program, including headers that you included. The reason is that a C program will and can behave differently if headers are missing. If you post code with no headers (as you did in your initial post), then there is no telling how the program will behave.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
OK, I am sorry, I see what you are saying. I am in the process of debugging, but since I am in windows, I cannot find a good debugger that will work well. I have visual studio, but it does not include all the classes that I am using in my program and from what I read it is not recommended to add them. Any suggestions on this?
Visual Studio has one of, if not, the most powerful debuggers out there. People debug all sorts of programs, from student programs to full-fledged systems of all types. So I don't know what you mean by "all the classes you're using".
I will cautiously say that you're not using the Visual Studio debugger correctly.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
//Function to prompt user if they don't enter all necessary switches
void Usage(char *progname)
{
fprintf(stderr,"Usage: %s -p [protocol] -e [port_num]\n", progname);
exit(1);
}
const char * getServer(char *svrList)
{
char *srList;
srList = strtok(svrList, " ," );
printf("Contents of srList b4 loop: %s\n", srList);
printf("Server List: %s\n", svrList);
while(srList !=NULL)
{
printf("result is \"%s\"\n", srList);
char pComm[512];
//memset(pComm, '\0', sizeof(512));
sprintf(pComm, "ping -c 1 %s > /dev/null", srList);
if((system (pComm))==0)
{
printf("result is \"%s\"\n", srList);
return ( srList );
}
else
{
printf("Hitting else loop\n");
srList = strtok(NULL, " ," );
printf("Contents of srList in else: %s\n", srList);
}
}
return "0";
}
int main(int argc, char *argv[])
{
//Declare global variables
char sendBuff[128];
const char *server_name= NULL;
unsigned short port;
int value, loopflag = 0;
int i, loopcount, maxloop=-1;
unsigned int addr;
int socket_type;
struct sockaddr_in server;
struct hostent *hp;
int connSocket;
char svrList[] = "129.120.151.254, 129.120.151.95, 129.120.151.96, 129.120.151.97";
//Check arguments
if (argc >1)
{
for(i=1; i<argc; i++)
{
// User can enter - or / as the switch
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
{
// Change lowercase, so switches aren't case-sensative
switch(tolower(argv[i][1]))
{
case 'p':
if (!strcasecmp(argv[i+1], "TCP"))
socket_type = SOCK_STREAM;
else if (!strcasecmp(argv[i+1], "UDP"))
socket_type = SOCK_DGRAM;
else
Usage(argv[0]);
i++;
break;
case 'n':
server_name = argv[++i];
break;
case 'e':
port = atoi(argv[++i]);
break;
default:
Usage(argv[0]);
break;
}
}
else
Usage(argv[0]);
}
}
// If port or socket type are missing, show user help command line
if (port == 0 || socket_type == 0)
{
Usage(argv[0]);
}
while(1)
{
printf("Checking which server to use.\n");
if (getServer(svrList) != "0")
{
server_name= getServer(svrList);
printf("The server is %s\n",server_name);
//Should we lookup hostname or just use IP
if (isalpha(server_name[0]))
{ // server address is a name
hp = gethostbyname(server_name);
}
else
{ // Convert to internet useable address
addr = inet_addr(server_name);
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
}
if (hp == NULL )
{
printf("Client: Cannot resolve address %s!", server_name);
exit(1);
}
else
printf("Client: Hostname setup successfully!\n");
// Copy the resolved information into the sockaddr_in structure
memset(&server, 0, sizeof(server));
memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
server.sin_family = hp->h_addrtype;
server.sin_port = htons(port);
connSocket = socket(AF_INET, socket_type, 0); /* Open a socket */
if (connSocket <0 )
{
printf("Client: Error Opening socket!\n");
return -1;
}
else
printf("Client: Socket established!\n");
// printf("Client: Client connecting to: %c.\n", server_name);
// addr = inet_addr(server_name);
// printf("%d\n", addr);
if (connect(connSocket, (struct sockaddr*)&server, sizeof(server)) < 0)
{
printf("Client: Can't connect to server!\n");
return -1;
}
else
printf("Client: Connected to server!\n");
// Gather input from user to send to server
printf("Please enter a floating point number: ");
float number1;
fscanf(stdin,"%f", &number1);
printf("Please enter a mathematical operator (+,-,*,/): ");
char mathOperator;
fscanf(stdin,"%c", &mathOperator);
fflush(stdin);
mathOperator = (char)fgetc(stdin);
printf("Please enter a floating point number: ");
float number2;
fscanf(stdin,"%f", &number2);
//Store input into buffer
sprintf(sendBuff, "%f,%f,%c", number1,number2,mathOperator);
value = send(connSocket, sendBuff, sizeof(sendBuff), 0);
printf("Client: Sending data complete!\n");
//Tell user was data was sent to server
printf("Client: Sent data \"%s\"\n", sendBuff);
//Receive the data back from the server
value = recv(connSocket, sendBuff, sizeof(sendBuff), 0);
printf("Client: Received data from the server!\n");
fflush(stdin);
//If the socket goes down, kill the connection
if (value == 0)
{
printf("Client: Server closed connection.\n");
close(connSocket);
return -1;
}
//Inform user what was received and terminate the connection
printf("Client: Received %d bytes, data \"%s\" from server.\n", value, sendBuff);
printf("Client: Terminating connection...\n");
//break;
//close(connSocket);
/* char cont;
printf("Do you want to continue? [Y/N]");
fscanf(stdin,"%s", &cont);
printf("%s\n", &cont);
if (cont = "Y" || "y")
{
continue;
}
else
{
break;
break;
} */
}
else
{
printf("There are no available servers!\n");
break;
}
}
return 0;
}
This is the full code for the client side. It works except for the getservers function. May not be the best as far as structure, but I just need to do certain things. The visual studio was giving me cannot open source file for the following:
#include <socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
I am assuming this means that these are classes that are used mainly in Linux and not windows.
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
I am assuming this means that these are classes that are used mainly in Linux and not windows.
Most of those headers are non-standard, more precisely the ones that deal with sockets. If you want to use sockets on both Windows and Linux, then you need to get a cross-platform solution, otherwise you have to write two different sets of code for Linux and Windows.
Secondly, sockets just confuse the issue. The problem is that you cannot take a string that is separated by commas, and produce each field -- in other words, a CSV parser. It doesn't matter what the data is going to be used for. If you wrote a simple function to do this first, then you can use any compiler to test the code since no sockets are involved. Instead, you're trying to learn basic 'C' coding within a larger program, and it's all of that unnecessary noise that this socket code is causing that is confusing the issue.
Code:
#include <stdio.h>
const char * getServer(char *svrList)
{
char *srList;
srList = strtok(svrList, " ," );
while(srList !=NULL)
{
char pComm[512];
sprintf(pComm, "ping -c 1 %s > /dev/null", srList);
if ((system (pComm))==0)
return srList;
else
srList = strtok(NULL, " ," );
}
return "0";
}
int main()
{
// write a test here
}
This is what you should be doing to test your code.
The first thing to realize is that strtok() messes up your original char array by placing NULLs in the data. Do you want that to happen? If not, then you need to copy the data to a temporary array and use that instead. The other thing is that strtok() can only be used in a "serial" way, i.e. you can't have two or more places where strtok() is being called interchangeably with different strings, where one strtok() is being called during the processing of the other strtok(). This is all due to strtok() using static variables.
http://www.cplusplus.com/reference/c...tok/?kw=strtok
Also, your code still doesn't suggest that it is really C that you're using. I still see variables being declared after executable statements, like this:
Code:
printf("Please enter a floating point number: ");
float number2;
If you tried to compile this with Visual Studio as a 'C' module, it will give you an error stating that you can't declare a float at that point in the code. Visual C++ follows the rules of ANSI 'C', and if you turned on the ANSI 'C' switch for gcc (that is if this is really and truly a 'C' program), you will get the same error using gcc. The only way to not get an error for this construct is if the code is C++, and so far, you haven't confirmed what language you're really compiling for.
If it is really C++, this job becomes much easier and safer.
Finally, you need to properly indent your code. It is almost impossible to follow with the indentation all over the place like that.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
So, the function is working like I want it to. When I run it by itself or output the result of the function to a printf, it has the correct return value. Where the problem comes in is when I call the function a second time. It seems like after this, something is different and it doesn't run the same the second time. I am referring to the code snippet that I added in my main program:
Code:
while(1)
{
printf("Checking which server to use.\n");
printf("Function return is: %s:\n", getServer(svrList));
if (getServer(svrList) != "0")
{
Then the output is this:
Code:
Checking which server to use.
Function return is: 129.120.151.95:
There are no available servers!
Which if you look at the main program, it is returning the "0" value on the second time the function is run, but the correct value the first time. Am I missing something in the way it is running the function?
-
Re: Help with C simple loop.
I haven't read the thread, but this is wonky.
return "0";
More than likely you mean
return 0;
or even better, return NULL; (same thing, just more clear)
When you test it here,
if (getServer(svrList) != "0")
you're actually comparing pointers, not the value they point to, so they'll never be equal. Return 0 and test for 0, not "0".
-
Re: Help with C simple loop.
Quote:
Originally Posted by
GCDEF
I haven't read the thread, but this is wonky.
return "0";
More than likely you mean
return 0;
or even better, return NULL; (same thing, just more clear)
When you test it here,
if (getServer(svrList) != "0")
you're actually comparing pointers, not the value they point to, so they'll never be equal. Return 0 and test for 0, not "0".
I changed the return to a NULL in the function and that line 'if (getServer(svrList) != "0")' to 'if (getServer(svrList) != NULL)' and it made no difference on the output. I do thank you for helping me with a better way of returning from the function. That helps me write a little better code. I know I am completely green right now.
-
Re: Help with C simple loop.
Code:
if (getServer(svrList) != "0")
You can't compare c-type NULL terminated strings like this. To compare these type of strings, you use
Code:
if (!strcmp(getServer(srvList) , "0"))
A better way as GCDEF said would be for getServer to return NULL instead of returning "0".
You also need to note, as said in previous posts, that strtok alters the contents of the string on which it is used. So if you call it more than once on the same string it will produce different answers! As said previously, copy the string first before using strtok. This is why calling getSever with the same argument more than once produces different results!
-
Re: Help with C simple loop.
Quote:
Originally Posted by
Paul McKenzie
The first thing to realize is that strtok() messes up your original char array by placing NULLs in the data. Do you want that to happen? If not, then you need to copy the data to a temporary array and use that instead. The other thing is that strtok() can only be used in a "serial" way, i.e. you can't have two or more places where strtok() is being called interchangeably with different strings, where one strtok() is being called during the processing of the other strtok(). This is all due to strtok() using static variables.
http://www.cplusplus.com/reference/c...tok/?kw=strtok
Also, your code still doesn't suggest that it is really C that you're using. I still see variables being declared after executable statements, like this:
Code:
printf("Please enter a floating point number: ");
float number2;
If you tried to compile this with Visual Studio as a 'C' module, it will give you an error stating that you can't declare a float at that point in the code. Visual C++ follows the rules of ANSI 'C', and if you turned on the ANSI 'C' switch for gcc (that is
if this is really and truly a 'C' program), you will get the same error using gcc. The only way to not get an error for this construct is if the code is C++, and so far, you haven't confirmed what language you're really compiling for.
If it is really C++, this job becomes much easier and safer.
Finally, you need to properly indent your code. It is almost impossible to follow with the indentation all over the place like that.
Regards,
Paul McKenzie
What can I use instead of strtok() because I will need to call this function multiple times to make sure that the server is still up and if not, move to the next one in the list, so dealing with a function that modifies my array is not good? I have verified in codelite that the string is being modified (not that I didn't believe you guys, just cool to see it for myself in the debugger). Also, as far as C versus C++, the requirement for this program is C, so I am kinda stuck on that one. I am still not sure why the code compiles with the way it is structured, but as long as it works, I can clean it up later. Just wanted to say I really appreciate the responses I have gotten on this, you guys are freakin awesome!!
-
Re: Help with C simple loop.
As said previously, in getServer copy the string first before using strtok and then use strtok on the copied string
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
What can I use instead of strtok() because I will need to call this function multiple times to make sure that the server is still up and if not, move to the next one in the list, so dealing with a function that modifies my array is not good?
There is no out-of-the-box 'C' function to parse without altering the string. You need to write it yourself or get one off the Net somewhere.
Quote:
Also, as far as C versus C++, the requirement for this program is C, so I am kinda stuck on that one.
The problem is that what you wrote violates C rules, so it isn't really a C program.
Quote:
I am still not sure why the code compiles with the way it is structured,
Please check all of your gcc command-line options. One of them is more than likely the ANSI switch that turns on ANSI C compilation. Once you compile with that option, you will see that the code I pointed out will fail to compile. I'm sure gcc has this option, as there still is a lot of 'C' code out there that requires ANSI 'C' compatibility without any extensions or C99 support.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
I think I finally got it!!! Thanks to you guys' help! The answer was the strcpy() function. One other question though, why can't I use a dynamic array with strcpy()? In the final code, I get an error if I use char *temp; but it works with char[512] as a static array. Couldn't find an explanation for that one. The explanation of strcpy says to prevent overflows, the size of destination has to be long enough to contain the same C string as source, but that doesn't explain why a dynamic array wouldn't work, because I would assume it should allocate it accordingly. That may be my wondering mind thinking without knowing how it works.... Also, do I have to have the exact array size as the source also or is it bad practice to add a little bit for "cushion"?
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char * getServer(char *svrList)
{
char temp[512];
strcpy (temp,svrList);
char *srList = NULL;
srList = strtok(temp, " ," );
while(srList !=NULL)
{
printf("result is \"%s\"\n", srList);
char pComm[512];
sprintf(pComm, "ping.exe -n 1 %s", srList);
if((system (pComm))==0)
return srList;
else
srList = strtok(NULL, " ," );
continue;
}
//return "0";
}
int main(int argc, char *argv[])
{
//Declare global variables
//char sendBuff[128];
const char *server_name= NULL;
// unsigned short port;
//int value, loopflag = 0;
//int i, loopcount, maxloop=-1;
//unsigned int addr;
//int socket_type;
//struct sockaddr_in server;
//struct hostent *hp;
//int connSocket;
char svrList[] = "129.120.151.254, 129.120.151.95, 129.120.151.96, 129.120.151.97";
while(1)
{
printf("Checking which server to use.\n");
if (getServer(svrList) != "0")
{
server_name= getServer(svrList);
printf("The server is %s\n",server_name);
//Should we lookup hostname or just use IP
break;
}
else
{
printf("There are no available servers!\n");
break;
}
}
return 0;
}
-
Re: Help with C simple loop.
Why is return commented out in getServer?
char* temp is an uninitialized pointer to unallocated memory.
-
Re: Help with C simple loop.
Quote:
Originally Posted by
willn
One other question though, why can't I use a dynamic array with strcpy()?
There is no such thing as a dynamic array in 'C'. All arrays are fixed in size.
Quote:
In the final code, I get an error if I use char *temp; but it works with char[512] as a static array.
There is a big difference between a pointer and an array. A pointer must point somewhere valid before you read or write to where it's pointing. Did you do that?
Quote:
The explanation of strcpy says to prevent overflows, the size of destination has to be long enough to contain the same C string as source, but that doesn't explain why a dynamic array wouldn't work, because I would assume it should allocate it accordingly.
C has none of these "automatic" facilities to resize strings or arrays. Arrays are fixed in size. The closest you can get is by using the heap (malloc(), calloc(), realloc(), etc.). However, once you go down that route, then you better know what you're doing.
That's why I asked whether you are really compiling a C++ module (that looks like it's C). With C++, you do have the facilities to resize strings and arrays using the various container and string classes.
Quote:
Also, do I have to have the exact array size as the source also or is it bad practice to add a little bit for "cushion"?
If you overflow the boundaries of the array, the result is undefined behaviour. Even if you're off by one byte, the program is flawed.
So yes, you should leave yourself more room, but that is not the greatest of solutions. The best solution would be to write a library of dynamic string routines for 'C', and use them instead of raw char* pointers and arrays. However, that is an undertaking for someone who knows 'C' fairly well and knows what to look out for.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
As to your code:
Code:
const char * getServer(char *svrList)
{
char temp[512];
strcpy (temp,svrList);
What if svrList points to a string that is more than 512 bytes? What if I pass a NULL to getServer()? Your code is now broken.
What is returned if the code falls through to this line that you commented out? The return value is now undefined.
Regards,
Paul McKenzie
-
Re: Help with C simple loop.
Quote:
Originally Posted by
Paul McKenzie
As to your code:
Code:
const char * getServer(char *svrList)
{
char temp[512];
strcpy (temp,svrList);
What if svrList points to a string that is more than 512 bytes? What if I pass a NULL to getServer()? Your code is now broken.
What is returned if the code falls through to this line that you commented out? The return value is now undefined.
Regards,
Paul McKenzie
As far as the more than 512 bytes, for what I am doing in this program and knowing that arrays cannot be dynamic in nature for 'C', I think my best bet is to just control the data that is in that array to make sure that a NULL or more than 512 bytes are not fed into the function. I know this is not the best way, but for this assignment, it will get me by.
Sorry about that, I changed it to return NULL; and changed my if statement below that.
As of right now, everything is working and the debugger helped a great deal! The only issue I am having now is:
I can't get this loop to break when I enter "N" at the prompt. It seems to completely skip the if true and false values and just continue running the while(1) loop. Am I missing something simple? I am just trying to continue the loop until the user enters anything other than Y or y. In the debugger, the value is getting put in "cont", but it just skips the continue or break on that if statement.
Code:
while(1)
{
printf("Checking which server to use.\n");
if (getServer(svrList) != "0")
{
server_name= getServer(svrList);
printf("The server is %s\n",server_name);
printf("Do you want to continue? [Y/N]");
fscanf(stdin,"%s", &cont);
printf("%s\n", &cont);
if (cont = "Y" || "y")
continue;
else
break;
}
else
{
printf("There are no available servers!\n");
break;
}
return 0;
}
-
Re: Help with C simple loop.
if (cont = "Y" || "y")
That's not how if statement works. Each side of the || is evaluated as an independent expression. "y" is a standalone expressions, and since it is non-zero, the if statement will always evaluate to true.
Why hot modify your while statement to look at cont, rather than have it continue indefinitely? while(1) is usually bad form.
-
Re: Help with C simple loop.
Quote:
Originally Posted by
GCDEF
if (cont = "Y" || "y")
That's not how if statement works. Each side of the || is evaluated as an independent expression. "y" is a standalone expressions, and since it is non-zero, the if statement will always evaluate to true.
Why hot modify your while statement to look at cont, rather than have it continue indefinitely? while(1) is usually bad form.
GCDEF, you are da man! I guess I just don't have the critical thinking to be able to handle some of this. That solution worked. I think that will do it. I know if I want to know best practices or any more help, I will definitely be back and will highly recommend this site to anyone! Can't thank you guys enough!