該函式使用 read() 從用戶那里獲取輸入,并使用 strtok 將其分解并將其放入陣列中。程式回圈直到遇到錯誤(我不會進入,因為這不是這里的問題)或者如果程式被用戶終止。但是,當它回圈回來并讀取用戶的輸入時,它似乎掛在用戶之前的輸入上。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#define BUFFERSIZE 1024
int main(int argc, char* argv[])
{
argc ;
char buf[BUFFERSIZE];
int n;
printf("Please enter commands: \n");
while ((n = read(STDIN_FILENO, buf, BUFFERSIZE)) > 0)
{
printf("original string: %s:\n", buf);
buf[strlen(buf)-1] = '\0';
printf("after change: %s:\n", buf);
int i = 0;
char* array[100];
char* token1 = strtok(buf, " ");
while ((token1 != NULL))
{
array[i ] = token1;
token1 = strtok(NULL, " ");
}//while
for (int j = 0; j < i; j )
{
printf("Array value %d: %s:\n", j, array[j]);
}//for
if (buf == "exit")
{
printf("found it\n");
}//if
for (int i = 1; i < argc; i )
{
pid_t pid;
if (argc >= 1)
{
if ((pid = fork()) < 0)
{
perror("fork");
}//if
else if (pid == 0)
{ // child process
if (execvp(array[0], array) == -1)
{
perror("execvp");
return EXIT_FAILURE;
} // if
}//else if
else
{ // parent process
int status;
wait(&status);
printf("Please enter commands again: \n");
}//else
}//if
else
{
fprintf(stderr, "Please specify the name of the program to exec as a command line argument\n");
return EXIT_FAILURE;
}//if
}//for
}//while
if (n == -1) perror("read");
}//main
我試圖清除陣列并清除“buf”但沒有運氣。我有一種感覺,它與 read() 以及“buf”保持其舊值這一事實有關。
uj5u.com熱心網友回復:
以我的最高評論開頭......
read不添加 0x00 的方式fgets,所以我們必須手動完成。execvp需要陣列以NULL條目終止。- 孩子應該使用
exit而不是return。
這是重構的代碼。是有注釋的。請注意,此代碼不執行緩沖區的拆分/連接以保證緩沖區以換行符結尾,如我的頂級評論所建議的那樣:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#define BUFFERSIZE 1024
int
main(int argc, char *argv[])
{
argc ;
char buf[BUFFERSIZE];
int n;
printf("Please enter commands: \n");
// NOTE/BUG: read does _not_ add 0x00 the way fgets does
#if 0
while ((n = read(STDIN_FILENO, buf, BUFFERSIZE)) > 0) {
#else
while ((n = read(STDIN_FILENO, buf, BUFFERSIZE - 1)) > 0) {
buf[n] = 0;
#endif
printf("original string: %s:\n", buf);
buf[strlen(buf) - 1] = '\0';
printf("after change: %s:\n", buf);
int i = 0;
char *array[100];
char *token1 = strtok(buf, " ");
while ((token1 != NULL)) {
array[i ] = token1;
token1 = strtok(NULL, " ");
}
// NOTE/BUG: execvp needs a NULL terminator
#if 1
array[i] = NULL;
#endif
for (int j = 0; j < i; j ) {
printf("Array value %d: %s:\n", j, array[j]);
}
// NOTE/BUG: wrong way to compare strings
#if 0
if (buf == "exit")
#else
if (strcmp(buf, "exit") == 0) {
printf("found it\n");
break;
}
#endif
for (int i = 1; i < argc; i ) {
pid_t pid;
if (argc >= 1) {
if ((pid = fork()) < 0) {
perror("fork");
}
// child process
else if (pid == 0) {
if (execvp(array[0], array) == -1) {
perror("execvp");
#if 0
return EXIT_FAILURE;
#else
exit(EXIT_FAILURE);
#endif
}
}
// parent process
else {
int status;
wait(&status);
printf("Please enter commands again: \n");
}
}
else {
fprintf(stderr, "Please specify the name of the program to exec as a command line argument\n");
return EXIT_FAILURE;
}
}
}
if (n == -1)
perror("read");
}
在上面的代碼中,我使用cpp條件來表示舊代碼與新代碼:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
注意:這可以通過運行檔案來清理unifdef -k
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/537845.html
標籤:数组C指针strtok
上一篇:求2個單鏈表的交集和并集
下一篇:HTML地址驗證模式
