c - 将非 ASCII 字符读入缓冲区
问题描述
我有一个多进程程序,它从命令行接收文件作为输入。创建共享内存,并为生产者/消费者风格的问题分叉。它每隔一个字节切换一次,生成 abcdef badcef。但是,我没有意识到这也必须允许非 ASCII 输入,我不知道该怎么做。我相信 wchar_t 允许非 ASCII 输入。但是我的函数如 fgets/strcpy 不能用于 wchar_t 数据类型呢?我找不到支持的功能替换。
请不要为我做整个问题,这是我班级的作业,但非常感谢一般建议。
我试过用 wchar_t 代替 char。我尝试使用 fgetsws 代替 fgets 但即使包含编译器也不会将 fgetsws 识别为库函数。我在 ubuntu linux 64 位机器上运行它。
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
}
解决方案
推荐阅读
- ios - 带有工具栏但没有文本字段的 UIDatePicker
- matlab - Matlab 从 .fig 格式的子图中提取图像
- json - Python/JSON - 如何从 JSON API 中选择特定值,就像在这种情况下,我想选择“权重”为最大值的配置文件
- c++ - 在 C++ 中使用回调
- javascript - 如何在 jquery.validation 中使用另一个属性而不是 name 属性?
- php - 停用特定用户角色的 wordpress 插件
- java - Java中的信号量和调度程序竞争条件
- c++ - 为什么编译器试图将 char * 转换为 char?
- c# - 将带有图像列的datagridview数据复制到剪贴板
- javascript - 将 DatePicker 对象重新绑定到 HTML 元素