gpt4 book ai didi

c - 使用 c 进行系统调用

转载 作者:行者123 更新时间:2023-11-30 17:20:12 25 4
gpt4 key购买 nike

嗨,我正在尝试用 c 语言创建几个管道,用于“服务器”和“接口(interface)”之间的通信。尽管我在调试时遇到问题,但遇到了一个奇怪的错误。我已经关注这个问题有一段时间了,但恐怕现在我已经忽略了它。任何帮助将不胜感激。

//server file
// include needed libraries
#include <errno.h> // system error numbers
#include <stdio.h> // Standard Input and Output Library
#include <stdlib.h> // Standard General Utilities Library
#include <string.h> // strings and arrays
#include <sys/types.h> // needed for pipes to work
#include <sys/wait.h> // for waitpid
#include <unistd.h> // sleep

#define BUFLENMES 65
#define BUFLEN2 1024

typedef struct {
char id[8];
int odometer;
float gallons;
} gasData;

// function prototype for comparing ID values
// using void in order to use built-in sort function
int compareID(const void *, const void *);

/**************** Main function *******************/
int main (int argc, char *argv[]) {

// initialize values for file reading
int iter = 0,
value = 0,
command,
outputFD;

// set up based on spaces used for delimtation
char id[8],
odometer[6],
gallons[8],
err,
buffer[BUFLEN2+1];

// get input and output file descriptors for pipes
err = sscanf (argv[1], "%d", &command);
if (err == 0) {
printf("Parameter must be an integer.\n");
exit(2);
}

err = sscanf (argv[2], "%d", &outputFD);
if (err == 0) {
printf("Parameter must be an integer.\n");
exit(2);
}

// initialize struct
gasData gasRecords[20];

// open file that contains the gas data
FILE *iFile;
iFile = fopen ("./gasData.txt", "r");

//read file for records
do {
value = fscanf (iFile, "%8s", id);
value = fscanf (iFile, "%6s", odometer);
value = fscanf (iFile, "%8s", gallons);

//store values in gasRecords struct
strcpy(gasRecords[iter].id, id);
sscanf (odometer, "%d", &gasRecords[iter].odometer);
sscanf (gallons, "%f", &gasRecords[iter].gallons);

// move to next record
iter++;
} while (value != EOF);

fclose(iFile);

// use iter to print records stored into struct
printf("\nRecords Stored\n");
for(int i = 0; i < (iter -1) ; i++) {
printf("element = %d: ", i);
printf("id = %s, ", gasRecords[i].id);
printf("odometer = %d, ", gasRecords[i].odometer);
printf("gallons = %f\n", gasRecords[i].gallons);
}
printf("\n");

/***************** act as server ****************/
int odom[iter-1],
count;

float averageMPG;
// checking commands
do {
char subString[8],
finalMessage[BUFLEN2+1],
message[BUFLENMES+1],
temp[20];

err = read (command, buffer, BUFLEN2);
if (err == -1 ) {
printf ("Error on read from pipe [server]: %d\n", errno);
exit (3);
}
buffer[BUFLEN2] = '\0';

if(strstr(buffer, "list,")) {
count = 0;

// get second part of command after the firs 5 chars
for(int i =0; i < 10; i++) {
subString[i] = buffer[i + 5];
}

// loop through structure for other IDs
for(int i =0; i < (iter-1); i++) {
if(!strcmp(gasRecords[i].id, subString)) {
odom[i] = gasRecords[i].odometer;
}
}

// sort using compareID below and qsort
qsort(odom, (iter-1), sizeof(int), compareID);

while(count < (iter-1)) {

// for each element in odom, check gasRecords
for(int i=0; i < (iter-1); i++) {

// if both the ID and the odometer match, send back to interface
if(!strcmp(gasRecords[i].id, subString) &&
odom[count] == gasRecords[i].odometer) {
char message2[65],
temp2[20];

sprintf(temp2, "element %d: ", i);
strcpy(message2, temp2);

sprintf(temp2, "id = %s, ", gasRecords[i].id);
strcat(message2, temp2);

sprintf(temp2, "odometer = %d, ", gasRecords[i].odometer);
strcat(message2, temp2);

sprintf(temp2, "gallons %f\n", gasRecords[i].gallons);
strcat(message2, temp2);
strcat(finalMessage, message2);
}
}
count++;
}
strcat(finalMessage, '\0');
err = write (outputFD, finalMessage, strlen(finalMessage)+1);
if (err == -1 ) {
printf ("Error on write to interface: %d\n", errno);
exit (3);
}
}
else if(strstr(buffer, "mpg,")) {
averageMPG = 0.0;
count = 0;

// get ID into subString
for(int i = 0; i < 10; i++) {
subString[i] = buffer[i + 4];
}

// search for mpg data for id and add it up
for(int i = 0; i < (iter-1); i++) {
if(!strcmp(gasRecords[i].id, subString)) {
averageMPG += gasRecords[i].gallons;
count++;
}
}

sprintf(temp, "Average MPG = %f\n", (averageMPG/count));
strcpy(message, temp);
message[BUFLENMES] = '\0';
err = write (outputFD, message, strlen(message)+1);
if (err == -1 ) {
printf ("Error on write to interface: %d\n", errno);
exit (3);
}
}

// if exit is entered print "response: Server complete."
else if(!strcmp(buffer, "exit")) {
strcpy(message, "Server complete");
message[BUFLENMES] = '\0';
err = write (outputFD, message, strlen(message)+1);
if (err == -1 ) {
printf ("Error on write to interface: %d\n", errno);
exit (3);
}

}

// check for invalid command
else {
strcpy(message, "Invalid command");
message[BUFLENMES] = '\0';
err = write (outputFD, message, strlen(message)+1);
if (err == -1 ) {
printf ("Error on write to interface: %d\n", errno);
exit (3);
}
}

} while(strcmp(buffer, "exit"));
return 0;
}

/****************** Function *********************/
int compareID(const void *first, const void *second) {
int f = *((int*)first);
int s = *((int*)second);

if (f > s)
return 1;
else if (s > f)
return -1;
else
return 0;
}

这是我的界面文件

// interface file 

#include <errno.h> // system error numbers
#include <stdio.h> // Standard Input and Output Library
#include <stdlib.h> // Standard General Utilities Library
#include <string.h> // strings and arrays
#include <sys/types.h> // needed for pipes to work
#include <sys/wait.h> // for waitpid
#include <unistd.h> // sleep

// define buffer length
#define BUFLEN 1024

int main (int argc, char *argv[])
{
int err,
i,
id,
status,
pError;

char buffer[BUFLEN+1],
command[20],
tochild[2],
toparent[2];

int toChild[2]; // if toChild[1], then writting to child
int toParent[2]; // if toParent[1], then writting to parent

// turning tochild into a pipe and checking for an error
err = pipe(toChild);
if ( err == -1) {
printf ("Error on pipe creation: %d\n", errno);
exit (1);
}

err = pipe(toParent);
if ( err == -1) {
printf ("Error on pipe creation: %d\n", errno);
exit (1);
}
// create child process
id = fork ();

// if id = 0, in child process
if ( id == 0 ) {

// set up pipes for passing into server
close (toChild[1]);
close (toParent[0]);
sprintf(tochild, "%d", toChild[0]);
sprintf(toparent, "%d", toParent[1]);
tochild[1] = '\0';
toparent[1] = '\0';

// exec into server, print records, and wait for instructions
err = execl("server", "server", tochild, toparent, 0);
if ( err == -1) {
printf ("Error on execl: %d\n", errno);
exit (1);
}
}
// if id > 0, in parent process
else if ( id > 0 ) {

close (toChild[0]);
close (toParent[1]);
sleep(1);

do {
printf("Input command: ");
scanf("%s", command);
command[19] = '\0';
err = write (toChild[1], command, strlen(command)+1);
if (err == -1 ) {
printf ("Error on write to pipe: %d\n", errno);
exit (3);
}
// parent reads back reponse from server read toParent[0]
err = read (toParent[0], buffer, BUFLEN);
if (err == -1 ) {
printf ("Error on read from pipe: %d\n", errno);
exit (3);
}

buffer[BUFLEN] = '\0';
printf ("Response: %s", buffer);
printf("\n");

} while(strcmp(command, "exit") != 0);
pError = waitpid(-1, &status, 0);
printf("Interface: child process (%d) completed.\n", id);
printf("Interface: child process exit status = %d.\n", status);
printf("Interface: Complete.\n");
exit (0);
}
else{
printf("Error creating forked process");
exit (4);
}

}

//编译和错误

csci2>g++ -o server Server.c
csci2>g++ Interface3.c
csci2>a.out

Records Stored
element = 0: id = red, odometer = 90229, gallons = 13.500000
element = 1: id = red, odometer = 90345, gallons = 14.500000
element = 2: id = red, odometer = 90453, gallons = 14.200000
element = 3: id = green, odometer = 23000, gallons = 32.000000
element = 4: id = green, odometer = 23300, gallons = 31.500000
element = 5: id = green, odometer = 23546, gallons = 37.799999
element = 6: id = , odometer = 120000, gallons = 23.700001
element = 7: id = , odometer = 120200, gallons = 24.670000
element = 8: id = , odometer = 120423, gallons = 26.799999
element = 9: id = 9045, odometer = 67321, gallons = 30.100000
element = 10: id = 9045, odometer = 67412, gallons = 15.900000
element = 11: id = 9045, odometer = 67689, gallons = 18.900000

Input command: mpg,red
Response: Average MPG = 14.066667

Input command: mgp,green
Response: Invalid command
Input command: mpg,green
Response: Average MPG = 33.766668

Input command: mpg,9045
Response: Average MPG = 21.633334

Input command: list,red
Response: Average MPG = 21.633334

Input command: list,red
Broken pipe

/* end */

值得注意的是,中间 ID 也没有正确传输。我有一个 .txt 文件,其中包含以下信息:

red 90229 13.5
red 90345 14.5
red 90453 14.2
green 23000 32.0
green 23300 31.5
green 23546 37.8
1489 120000 23.7
1489 120200 24.67
1489 120423 26.8
9045 67321 30.1
9045 67412 15.9
9045 67689 18.9

最佳答案

我想我知道出了什么问题,就是这个

buffer[BUFLEN] = '\0';

如果收到的消息小于该值,那么您没有 nul 正确终止字符串,您应该

buffer[err] = '\0';

因为read()返回成功读取的字节数。

当然,这同样适用于这个buffer[BUFLEN2] = '\0';

关于c - 使用 c 进行系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28666318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com