FaridAgl Posted January 27, 2014 Share Posted January 27, 2014 I'm trying to parse this: char *szCSV = "1,qw.ryui-opas_fgh,6da1ef8d8fc0cafcwfcc9r34d8302cb3,asdfasda85ffcfes7f2v1sfdfsd1f4ss"; To something like this: char *szArr[] = {"1", "qw.ryui-opas_fgh", "6da1ef8d8fc0cafcwfcc9r34d8302cb3", "asdfasda85ffcfes7f2v1sfdfsd1f4ss"}; Any help/tips would be great. http://faridaghili.ir Link to comment Share on other sites More sharing options...
Mat Posted January 27, 2014 Share Posted January 27, 2014 Replace any commas with null characters, and store the pointers to the first character of each item. AutoIt Project Listing Link to comment Share on other sites More sharing options...
FaridAgl Posted January 27, 2014 Author Share Posted January 27, 2014 Thanks Mat, I can imagine how that should work, but I guess I don't have the enough skill for that. Can I ask for a working code please? However I'm going to try it. http://faridaghili.ir Link to comment Share on other sites More sharing options...
trancexx Posted January 27, 2014 Share Posted January 27, 2014 Working example would really depend on your actual code. The way you've put things, Mat's idea wouldn't work because szCSV is read-only. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
FaridAgl Posted January 27, 2014 Author Share Posted January 27, 2014 Well, you are right. LPSTR szCSV = "1,qw.ryui-opas_fgh,6da1ef8d8fc0cafcwfcc9r34d8302cb3,asdfasda85ffcfes7f2v1sfdfsd1f4ss"; DWORD i = 0; while (szCSV[i] != NULL) { if (szCSV[i] == ',') { szCSV[i] = NULL; } i++; } This code gives me "Access violation writing location" error. I'm working on a socket server, a multithread one, here it is: expandcollapse popup#define RECV_BUF_LEN 92 DWORD WINAPI ClientSocketThread(LPVOID lpParameter) { SOCKET s = *(SOCKET *)lpParameter; char buf[RECV_BUF_LEN]; if (recv(s, buf, RECV_BUF_LEN, 0) <= 0) { closesocket(s); printf_s("recv failed.\n"); return 0; } char msg[] = "Thanks, I've read that."; send(s, msg, strlen(msg), 0); if (shutdown(s, SD_BOTH) == SOCKET_ERROR) { closesocket(s); printf_s("shutdown failed.\n"); return 0; } closesocket(s); return 0; } int _tmain(int argc, _TCHAR* argv[]) { WSADATA WSAData; if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) { printf_s("WSAStartup failed.\n"); goto Finish; } else { if (LOBYTE(WSAData.wVersion) != 2 || HIBYTE(WSAData.wVersion) != 2) { WSACleanup(); printf_s("Could not find a usable version of Winsock.dll.\n"); goto Finish; } } addrinfo Hints; ZeroMemory(&Hints, sizeof(Hints)); Hints.ai_family = AF_INET; Hints.ai_socktype = SOCK_STREAM; Hints.ai_protocol = IPPROTO_TCP; Hints.ai_flags = AI_PASSIVE; addrinfo *Result = NULL; if (getaddrinfo("127.0.0.1", "1234", &Hints, &Result) != 0) { WSACleanup(); printf_s("getaddrinfo failed.\n"); goto Finish; } SOCKET s = socket(Result->ai_family, Result->ai_socktype, Result->ai_protocol); if (s == INVALID_SOCKET) { freeaddrinfo(Result); WSACleanup(); printf_s("socket failed.\n"); goto Finish; } if (bind(s, Result->ai_addr, (int)Result->ai_addrlen) == SOCKET_ERROR) { closesocket(s); freeaddrinfo(Result); WSACleanup(); printf_s("bind failed.\n"); goto Finish; } freeaddrinfo(Result); if (listen(s, SOMAXCONN) == SOCKET_ERROR) { closesocket(s); WSACleanup(); printf_s("listen failed.\n"); goto Finish; } SOCKET socket = INVALID_SOCKET; while (true) { socket = accept(s, NULL, NULL); if (socket == INVALID_SOCKET) { printf_s("accept failed.\n"); continue; } CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)ClientSocketThread, &socket, 0, NULL); } closesocket(s); WSACleanup(); Finish: system("Pause"); return 0; } It receives the message sent by the client (which will be CSV formatted), and will send the proper data back. Currently I'm on the "CSV Parser" step! And I have to parse buf variable in the ClientSocketThread to an array, like I had explained in the first post. http://faridaghili.ir Link to comment Share on other sites More sharing options...
trancexx Posted January 27, 2014 Share Posted January 27, 2014 It's ok then because your buf is allocated on the stack, you can do whatever you want with it, meaning your OP's szCSV is more like this: char szCSV[] = "1, qw.ryui - opas_fgh, 6da1ef8d8fc0cafcwfcc9r34d8302cb3, asdfasda85ffcfes7f2v1sfdfsd1f4ss"; ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
FaridAgl Posted January 27, 2014 Author Share Posted January 27, 2014 Yes, my miss, thanks. Any change of seeing any example? I can replace commas with null but I'm not able to create a new variable for each of them (Something like what Mat said). I guess I don't have the skill. Thanks in advance. http://faridaghili.ir Link to comment Share on other sites More sharing options...
trancexx Posted January 27, 2014 Share Posted January 27, 2014 This could be one way to do what you want: expandcollapse popupchar buf[RECV_BUF_LEN] = {}; // zero-ed out //...the rest of your code that fills the buf... // Calculate how many chunks of strings are in your buf int ibound = 0; for (int i = 0; i < RECV_BUF_LEN; ++i) { if (buf[i] == ',') { buf[i] = '\0'; ++ibound; } } // Now you allocate space for calculated number of (string) pointers char** szArr = new char*[ibound + 1]; for (int j = 0, i = 0; j <= ibound; ++j) { szArr[j] = &buf[i]; // set this pointer to your array for (; i < RECV_BUF_LEN; ++i) { if (buf[i] == '\0') { ++i; // skip this one if (buf[i] == ' ') ++i; // skip "space" too break; } } } // Print elements of your array just because for (int i = 0; i <= ibound; ++i) printf("%i. %s\n", i, szArr[i]); // Free dynamically allocated array (don't forget this) delete[] szArr; fflush(stdout); // flush to see what's printed ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Mat Posted January 27, 2014 Share Posted January 27, 2014 expandcollapse popup#define LPSTR char* #define TCHAR char #define DWORD unsigned long #include <string.h> #include <stdio.h> #define RECV_BUF_LEN 92 LPSTR szCSV = "1,qw.ryui-opas_fgh,6da1ef8d8fc0cafcwfcc9r34d8302cb3,asdfasda85ffcfes7f2v1sfdfsd1f4ss"; int main() { TCHAR buff[92]; LPSTR parts[4] = {buff, 0}; // Assuming there is always 4 elements? // Mimics the recieving from the socket strncpy(buff, szCSV, RECV_BUF_LEN); TCHAR* ch = &buff[0]; int p = 1; while (*ch) { if (*ch == ',') { *ch = '\0'; parts[p++] = ch+1; } ch++; } for (p = 0; p < 4; p++) { puts(parts[p]); } return(0); } Not very tidy, but should give you an idea of how I'd approach it. AutoIt Project Listing Link to comment Share on other sites More sharing options...
funkey Posted January 27, 2014 Share Posted January 27, 2014 Just similar to my version: Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
FaridAgl Posted January 27, 2014 Author Share Posted January 27, 2014 trancexx Thank you so much, specially for the comments. I'm going to give it a try. Mat Thank you, I will give it a try too. No, that's not always 4 elements, but the first character ('1' in this example) could be used to know how many elements is there. A value of 1 means there are a total of 4 elements, A value of 2 = 4 elements A value of 3 = 3 elements 4 = 4 elements 5 = 3 elements 1 means Login request, 2 means CheckIn request, 3 mean Password Reset request, 4 means Password Change request and 5 means Logout request. 1 = 1,Username,PasswordAsMD5,MachineId 2 = 2,Username,PasswordAsMD5,MachineId 3 = 3,Username,Email 4 = 4,Username,CurrentPasswordAsMD5,NewPassword 5 = 5,Username,MachineId funkey Thanks, I will check that thread as soon as I finished with the above codes... http://faridaghili.ir Link to comment Share on other sites More sharing options...
jaberwacky Posted January 27, 2014 Share Posted January 27, 2014 expandcollapse popupchar buf[RECV_BUF_LEN] = {}; // zero-ed out //...the rest of your code that fills the buf... // Calculate how many chunks of strings are in your buf int ibound = 0; for (int i = 0; i < RECV_BUF_LEN; ++i) { if (buf[i] == ',') { buf[i] = '\0'; ++ibound; } } // Now you allocate space for calculated number of (string) pointers char** szArr = new char*[ibound + 1]; for (int j = 0, i = 0; j <= ibound; ++j) { szArr[j] = &buf[i]; // set this pointer to your array for (; i < RECV_BUF_LEN; ++i) { if (buf[i] == '\0') { ++i; // skip this one if (buf[i] == ' ') ++i; // skip "space" too break; } } } // Print elements of your array just because for (int i = 0; i <= ibound; ++i) printf("%i. %s\n", i, szArr[i]); // Free dynamically allocated array (don't forget this) delete[] szArr; fflush(stdout); // flush to see what's printed Clueless here. Hi. Sorry to hijack. Why does szArr need to be a **? I assume that means an array of pointers to pointers? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
trancexx Posted January 27, 2014 Share Posted January 27, 2014 ^^ It means pointer to array of pointers.You should see AutoIt source. At one place it has Variant***. jaberwacky 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Solution FaridAgl Posted January 28, 2014 Author Solution Share Posted January 28, 2014 trancexx Thanks a lot, you were really helpful, as always of course. Here is what I came up with finally: expandcollapse popupLPSTR *StringToCsv(CHAR buf[], int *nBound) { int i = 0, j = 0; *nBound = 0; while (buf[i] != '\0') { if (buf[i] == ',') { buf[i] = '\0'; *nBound += 1; } i++; } *nBound += 1; char **szArray = new char *[*nBound]; for (j = 0, i = 0; j <= *nBound - 1; j++) { szArray[j] = &buf[i]; while (buf[i] != '\0') { i++; if (buf[i] == '\0') { i++; break; } } } return szArray; } Mat, thank you too. http://faridaghili.ir Link to comment Share on other sites More sharing options...
jaberwacky Posted January 28, 2014 Share Posted January 28, 2014 (edited) Ahhhh, pointer to an array of pointers makes a lot more sense. And I learned something new today. Yay! Thx trancexx. Urm, but what could Variant*** possibly mean? A pointer to a pointer to a pointer to a type Variant? Also, what turn of events occurred to even create a spawn? Edited January 28, 2014 by jaberwacky Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
jaberwacky Posted January 28, 2014 Share Posted January 28, 2014 (edited) Oh, Variant*** is a pointer to a container of pointers to variants isn't it? Edit, no, probably not actually. Edited January 28, 2014 by jaberwacky Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
trancexx Posted January 29, 2014 Share Posted January 29, 2014 (edited) Oh, Variant*** is a pointer to a container of pointers to variants isn't it? Edit, no, probably not actually.It's not that hard to imagine what it would be needed for.If you look at the code posted here char*** could have been used as well to pass pointer to szArr to some function that would do allocation:void Allocate(char*** xy, int size) { *xy = new char*[size + 1]; } //... char** szArr; Allocate(&szArr, ibound);But since this is C++, it's more correct to do it like this, if you are doing it that way:void Allocate(char**& xy, int size) { xy = new char*[size + 1]; } //... char** szArr; Allocate(szArr, ibound); Edited January 29, 2014 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
FaridAgl Posted January 29, 2014 Author Share Posted January 29, 2014 Looks like the night sky, so many stars http://faridaghili.ir Link to comment Share on other sites More sharing options...
jaberwacky Posted January 29, 2014 Share Posted January 29, 2014 It's not that hard to imagine what it would be needed for. Easy for you to say. I think this seals the deal. I'll never be ready for prime time when it comes down to c++. Thanks for taking the time to show me that! Appreciate it. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Gianni Posted January 29, 2014 Share Posted January 29, 2014 That C++ code to FlowChart with this site: http://code2flow.com/ it help me to see the overall logic of the above program. I would love a tool like that (code2flow.com), for the AutoIt language, were included in this site autoitscript.com... Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now