The essence of the program is that the client sends the path to the folder, the server accepts it and, by analogy with the DIR utility, finds the folders inside it and sends them to the client, the client already displays these folders. So the problem is that when the server finds them, it sends them to the client, let's say a pack. For example:

Windows

System

Config

And when I output them via printf, only Windows is output. This problem is that printf prints until it meets \0 and it turns out my this pack looks like this:

Windows \ 0

System \ 0

Config \ 0

The transfer programs themselves:

 while (1) { // Получаем очередную команду через канал Pipe if (ReadFile(hNamedPipe, szBuf, 512, &cbRead, NULL)) { DIR *dir; struct dirent *entry; dir = opendir(szBuf); if (!dir) { perror("diropen"); exit(1); }; while ((entry = readdir(dir)) != NULL) { printf("%s\n", entry->d_name); if (!WriteFile(hNamedPipe, entry->d_name, strlen(entry->d_name) + 1, &cbWritten, NULL)); }; if (!WriteFile(hNamedPipe, "|" , strlen(szBuf) + 1, &cbWritten, NULL)); closedir(dir); 

Reception:

 // Передаем введенную строку серверному процессу // в качестве команды if (!WriteFile(hNamedPipe, szBuf, strlen(szBuf) + 1, &cbWritten, NULL)) break; // Получаем папку от сервера do { if (ReadFile(hNamedPipe, szBuf, 512, &cbRead, NULL)) printf("Received back: <%s>\n", szBuf); // Если произошла ошибка, выводим ее код // завершаем работу приложения else { fprintf(stdout, "ReadFile: Error %ld\n", GetLastError()); _getch(); break; } } while (szBuf != "|"); 

I just want to know how to read the data correctly? If you remove the addition of \ 0, that is, remove +1, then it displays everything correctly but all in one line: WindowsSystemConfig, etc.

  • And who prevents simply scan the line next? Well, zero, so what? We take and go on. How many TOTAL bytes - we know, Wath and go, until we reach the end ... - Harry
  • @Harry I get so that these folders, which are transmitted in a pack, will be displayed together and as one line. How to make it right? I was told that it is fashionable to do it through memset. But I have no idea how to do this. - Anrey
  • Brought the first. Became on its end. Is this not the end of everything? Not? So, we start with a new symbol and display the following. And so, until everything is displayed. Or, for example, at the end add another extra null character, i.e. a blank line at the end is a sign of the end. - Harry
  • @Harry and if it doesn't bother you with an example code? I do not catch up with how to implement simply. - Anrey pm
  • one
    Because at least szBuf will never be equal to "|" . "|" - this is a string with its address, szBuf is another address, a buffer. And why should they coincide? Equality of the contents of strings is checked using functions like strcmp ... - Harry

3 answers 3

The printf function returns the number of characters printed, excluding the terminating zero. This can be used to define line endings:

 if(ReadFile(hNamedPipe, szBuf, 512, &cbRead, NULL)) { auto format_string = "Received back: <%s>\n"; const auto format_len = strlen(format_string) - 2; int c = printf(format_sting, szBuf); if(0 <= c) { c -= format_len; for(int i = c + 1; i < cbRead; i += c + 1) { c = printf(format_sting, szBuf + i); if(0 > c) { // ошибка } c -= format_len; } } } 
  • Received back: - this is you also considered the same. - Qwertiy
  • @Qwertiy Operdil :) - Cerbo pm
  • It looks easier for me :) And there are no extra length calculations. - Qwertiy
  • @Cerbo thank you very much, figured it out. And here's another small question, it turns out I implemented the read until the "|" character comes it comes to me, but there is a looping, do not know why? - Anrey
  • one
    @Anrey If you are talking about this while(szBuf != "|") , This is not surprising because you are comparing pointers here and not strings. They will never be equal. This is how it should be: while(0 != strcmp(szBuf, "|")) , or so while(*szBuf != '|') - Cerbo

Add an extra zero when sending at the end - so that the structure was like this ... (There are even 2 extra zeroes here - I just did it so that it was clearer). This is easiest:

 char * output= "Windows\0Program Files\0Users\0Prochaya khren\0\0"; void print(const char * out) { for(const char * c = out; *c; c += strlen(c)+1) printf("<%s>\n",c); } int main(int argc, const char * argv[]) { print(output); } 
  • You can do without strlen . - Qwertiy
  • @Qwertiy Can. Either scan or assume that printf prints. But if he prints something complicated, then it is difficult, and %n not recommended to be used. And if there is no printf , but some other processing? Or what do you mean? - Harry
  • Can you provide an example when %n leads to errors? (except for the opinion of M $ security experts ) - avp
  • Yes, I do not remember exactly. Where I read - in Sikorda, "Safe programming in C and C ++." If it is very important - remind tomorrow :), now I turn off the computer - then I will look for a book and what they wrote ... - Harry
  • In general, I am not too important. And write, for example, in man on printf write an obvious thing - Code such as printf(foo); often indicates a bug, since foo may contain a % character. If foo comes from untrusted user input, it may contain %n, causing the printf() call to write to memory and creating a secuity hole. Code such as printf(foo); often indicates a bug, since foo may contain a % character. If foo comes from untrusted user input, it may contain %n, causing the printf() call to write to memory and creating a secuity hole. , but it’s still not about the explicit format, but about untrusted user foo - avp

http://ideone.com/pKA3Zp
http://ideone.com/ffjDAv

 #include <cstdio> char *names = "Windows\0System\0Config\0"; int main() { int l, r; for (char *name=names; *name; name+=r-l+1) if (printf("Folder: %n%s%n\n", &l, name, &(r=0)), !r) break; // Произошла ошибка, вероятно, стоит что-то сделать return 0; } 
  • And l and r not initialized, what do you teach the youth? - Cerbo
  • %n - ready hole for hacking, generally speaking ... - Harry
  • 2
    @Cerbo, they are initialized by printf. - Qwertiy
  • @Harry, show me how to break this code? - Qwertiy
  • @Qwertiy How exactly is the compiler compiled? :) In a word, read R. Sykorda Safe programming in C and C ++ - it describes in detail how. And in MSDN they write this: Since the format of% n is unsafe, by default it is not allowed. If the format string contains the character% n, the handler for the invalid parameter is called, as described in the section Checking Parameters. To enable support for% n, see the _set_printf_count_output section. - Harry