I'm trying to get two strings written to stdout character by character by two different processes, father and child, being the use of read() and write() compulsory, with the following code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
char buf1[100];
char buf2[100];
int i;
pid_t t;
int main()
{
printf("String1:\n");
read(0, buf1, 100);
printf("String2:\n");
read(0, buf2, 100);
t = fork();
if (t > 0) {
wait(NULL);
for (i = 0; i < strlen(buf2); i ) {
write(1, &buf2[i], 1);
sleep(1);
}
}
else {
for (i = 0; i < strlen(buf1); i ) {
write(1, &buf1[i], 1);
sleep(1);
}
exit(0);
}
return(0);
}
I manage to get two processes writing each one a single string to stdout, but I'm failing in merging those two strings into one. I've tried to use the ANSI Escape Codes to get the cursor ready for the second string where the first string ends, but how could I integrate them into the buffers inside write()?
Now, with the above mentioned code, I can obtain this output:
String1:
Hyper
String2:
loop
Hyper
loop
I'd like to obtain:
String1:
Hyper
String2:
loop
Hyperloop
Thank you in advance
CodePudding user response:
@chux already addressed the main issue. Here is the corresponding working code with the following other changes:
- localized or eliminated variables
- added the missing includes to get this to compile on Linux
- replaced the
write
per character with a sleep with just a singlewrite
for the entire string - guard against buffer overflow
- define LEN instead of inline magic values, also use STDOUT_FILENO
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define LEN 99
#define str(s) xstr(s)
#define xstr(s) #s
int main() {
char buf1[LEN 1];
char buf2[LEN 1];
printf("String1:\n");
scanf("%" str(LEN) "s", buf1);
printf("String2:\n");
scanf("%" str(LEN) "s", buf2);
if (fork() > 0) {
wait(NULL);
write(STDOUT_FILENO, buf2, strlen(buf2));
} else {
write(STDOUT_FILENO, buf1, strlen(buf1));
exit(0);
}
return(0);
}
and here is the output (note there is no newline after the last line):
String1:
Hyper
String2:
loop
Hyperloop
Not sure why you print a letter at a time, but the better alternative is just printf("%s", buf)
(where but is either buf1
or buf2
).
CodePudding user response:
I think I've found a solution. The last byte read by read() or written by write() correspond to the newline. So writing all the bytes of the first buffer but one is crucial to get the results I want. In this way, the first buffer's for loop would be as follows:
for (i = 0; i < strlen(buf1)-1; i ) {
write(1, &buf1[i], 1);
sleep(1);
}
And being the complete code like this:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
char buf1[100];
char buf2[100];
int i;
pid_t t;
int main()
{
printf("String1:\n");
read(0, buf1, 100);
printf("String2:\n");
read(0, buf2, 100);
t = fork();
if (t > 0) {
wait(NULL);
for (i = 0; i < strlen(buf2); i ) {
write(1, &buf2[i], 1);
sleep(1);
}
}
else {
for (i = 0; i < strlen(buf1)-1; i ) {
write(1, &buf1[i], 1);
sleep(1);
}
exit(0);
}
return(0);
}
Thanks a lot to the helpers!