Чтение не-ASCII символов в буфер - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть многопроцессорная программа, которая получает файл в качестве ввода из командной строки. Создает разделяемую память и разветвляется для проблемы в стиле производителя / потребителя. Он переключает каждый второй байт, делая 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(&mutex1);
              sortstring(buff); //switch bytes in the buffer
              pthread_mutex_unlock(&mutex1);
              while (shmem->size != 0)
              {
                   waitchild(); // wait for child to read from buff
              }
              pthread_mutex_lock(&mutex1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              strcpy(shmem->data, buff); //replacement for strcpy?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              pthread_mutex_unlock(&mutex1);
              pthread_mutex_lock(&mutex1);
              shmem->size= strlen(shmem->data); //set size to strlen of data
              pthread_mutex_unlock(&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.\n\n");
     }   //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(&nomask); //empty mask
     sigemptyset(&new);
     sigaddset(&new, SIGUSR1); //add sigusr1 signal to mask
     sigprocmask(SIG_BLOCK,&new,&old); //block new/old signals
}
void waitchild()
{
     while (shflag==0)
     {
          sigsuspend(&nomask); //wait on child signal
     }
     shflag=0; //reset flag
     sigprocmask(SIG_SETMASK,&old,NULL);
}
void waitparent()
{
     while (shflag==0)
     {
          sigsuspend(&nomask); //wait for parent
     }
     shflag=0; //reset flag
     sigprocmask(SIG_SETMASK,&old,NULL);
}
void childsig(pid_t pid)
{
     kill(pid,SIGUSR1);  //sends parent signal
}
void parentsig(pid_t pid)
{
     kill(pid,SIGUSR1); //sends child signal
}
...