#c #linux #string #non-ascii-characters #multiprocess
#c #linux #строка #символы, отличные от ascii #многопроцессорный
Вопрос:
У меня есть многопроцессорная программа, которая получает файл в качестве входных данных из командной строки. Создает разделяемую память и разветвляется для проблемы в стиле производителя / потребителя. Он переключает каждый второй байт, делая abcdef badcef. Однако я не понял, что это также должно допускать ввод, отличный от ASCII, и я не знаю, как это сделать. Я считаю, что wchar_t допускает ввод, отличный от ASCII. Но как насчет моих функций, таких как fgets / strcpy, которые не работают с типом данных wchar_t? Я не могу найти поддерживаемые замены функций.
Пожалуйста, не делайте всю проблему за меня, это задание для моего класса, но общие советы очень ценятся.
Я пытался использовать wchar_t вместо char . Я пытался использовать fgetsws вместо fgets, но даже при включении компилятор не распознает fgetsws как библиотечную функцию. Я запускаю это на 64-разрядной машине ubuntu linux.
pa2.h================================================
#ifndef pa2_h
#define pa2_h
int shflag;
sigset_t new, old, nomask;
struct shbuff
{
char data[1024];
int size;
};
void flagfunc();
void block();
void sortstring(char input[]);
void waitchild();
void waitparent();
void parentsig(pid_t pid);
void childsig(pid_t pid);
#endif
pa2.c==========================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include "pa2.h"
int main(int argc, char* argv[])
{
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pid_t pid;
int mem;
FILE* fpinput;
FILE* fpout;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
char buff[1024]; // Do I conver this to wchar_t data type?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
key_t shkey;
void *ptr =0;
struct shbuff* shmem;
if(argc < 2)
{
printf("Input a file name including .txt!");
exit(1);
}
block(); //block sigusr1
pid=fork(); // child gets pid 0, parent is positive int
if(pid != 0) // parent process
{
fpinput= fopen(argv[1], "r"); // read from file
mem= shmget(shkey, sizeof(struct shbuff), IPC_CREAT | 0666); //size rounded up to nearest page size / 0666 required for server read/write
ptr= shmat(mem, (void *)0, 0); // Attach the shared memory
shmem= (struct shbuff *) ptr;
shmem->size= 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
while (fgets(buff,1023,fpinput) != NULL) //read in from file to buffer leaving room for terminating character
// Do I use fgetsws to replace this fgets?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
pthread_mutex_lock(amp;mutex1);
sortstring(buff); //switch bytes in the buffer
pthread_mutex_unlock(amp;mutex1);
while (shmem->size != 0)
{
waitchild(); // wait for child to read from buff
}
pthread_mutex_lock(amp;mutex1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
strcpy(shmem->data, buff); //replacement for strcpy?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pthread_mutex_unlock(amp;mutex1);
pthread_mutex_lock(amp;mutex1);
shmem->size= strlen(shmem->data); //set size to strlen of data
pthread_mutex_unlock(amp;mutex1);
childsig(pid); // signal to parent
}
while (shmem->size != 0)
{
waitchild(); // wait for child to read from buff
}
shmem->size= -1; //end of file
childsig(pid); //send signal
fclose(fpinput); //close file
shmdt(shmem); // detach from shared memory
printf("Transferred.nn");
} //end of else if (pid != 0)
else //if pid is 0 then process the child
{
fpout= fopen("output.txt", "w");
mem= shmget(shkey, sizeof(struct shbuff), IPC_CREAT | 0666); //size rounded up to nearest page size / 0666 required for server read/write
ptr= shmat(mem, (void *)0, 0); // attach to shared memory
shmem= (struct shbuff*) ptr; //convert the sharedMemory into struct
while (shmem->size != -1) // while not EOF
{
while (shmem->size == 0)
{
waitparent(); //wait for the child to read from shared memory
}
if (shmem->size != -1) //if not EOF
{
fputs(shmem->data,fpout); //copy the contents into the outFile
shmem->size = 0; //re-zero size after emptying data buffer
parentsig(getppid()); //parent signal
}
}
fclose(fpout); // closes output file
shmdt(shmem); // detach shared memory
kill(getpid(),SIGTERM); // Kills this process politely with sigterm rather than sigkill, We are civilized
}
exit(0);
}
void flagfunc()
{
shflag = 1;
}
void sortstring(char input[]){
char temp;
int i= 0;
for(i=0; i<strlen(input); i =2){
temp= input[i];
input[i]= input[i 1];
input[i 1]= temp;
}
}
void block()
{
signal(SIGUSR1,flagfunc);
sigemptyset(amp;nomask); //empty mask
sigemptyset(amp;new);
sigaddset(amp;new, SIGUSR1); //add sigusr1 signal to mask
sigprocmask(SIG_BLOCK,amp;new,amp;old); //block new/old signals
}
void waitchild()
{
while (shflag==0)
{
sigsuspend(amp;nomask); //wait on child signal
}
shflag=0; //reset flag
sigprocmask(SIG_SETMASK,amp;old,NULL);
}
void waitparent()
{
while (shflag==0)
{
sigsuspend(amp;nomask); //wait for parent
}
shflag=0; //reset flag
sigprocmask(SIG_SETMASK,amp;old,NULL);
}
void childsig(pid_t pid)
{
kill(pid,SIGUSR1); //sends parent signal
}
void parentsig(pid_t pid)
{
kill(pid,SIGUSR1); //sends child signal
}
Комментарии:
1. Наиболее распространенным сценарием для многобайтовых символов является использование UTF-8. Вы можете читать и записывать его, как если бы это был ascii, используя обычные функции ASCII. Затем вы можете использовать mbrtowc для преобразования из
char*
вwchar_t*
и wcrtomb для возврата. Это поможет вам пройти большую часть пути2. «Не-ASCII» сам по себе бессмысленный термин. EBCDIC не является ASCII. Предполагается ли, что ваша программа читает EBCDIC? Вам нужно точно знать кодировку, с которой вы пытаетесь работать. Нужная вам функция написана по буквам
fgetws
.3.
fgetws
однако не гарантируется работа с UTF-8. Это зависит от вашего компилятора.