尝试在 2D 数组上使用 strtok() 时出现段错误

发布于 2024-12-06 18:39:51 字数 2137 浏览 0 评论 0原文

我希望有人能帮助我弄清楚为什么我的代码出现分段错误。我的用户输入了一行文本,该文本被传递给解析函数。解析函数应该初始化一个二维数组(理想情况下我希望动态分配该数组,但现在我将其设为大小为 [25][25] 的数组)。

input 开头开始调用 strtok()。如果 strtok() 看到管道符号,它应该增加管道的数量并转到矩阵的下一行。例如,如果用户输入 foo bar | foo1 | foo2 bar1 foo2,二维数组看起来像:

array[][] = { foo, barr;
              foo1;
              foo2, bar1, foo2; }

最终我想将此数组传递给另一个函数。但是,如果我实际上将上述内容输入到我的程序中,结果如下:

/home/ad/Documents> foo bar | foo1 | foo2 bar1 foo2
test1
Segmentation fault
ad@ad-laptop:~/Documents$

因此,考虑到我放置这些调试语句的位置,问题在于保存令牌?这是我第一次使用二维数组,所以我确信我的指针逻辑有问题。我该如何修复此分段错误?感谢您抽出时间。

代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int MAX_PATH_LENGTH = 1024; //Maximum path length to display.
int BUF_LENGTH = 1024; // Length of buffer to store user input
char * delims = "|"; // Delimiters for tokenizing user input.
const int PIPE_READ = 0;
const int PIPE_WRITE = 1;

void execute(char *args, int numPipes, int numArgs){
    int i;
    int j;
    for(i = 0; i <= numArgs; i++){
        for(j = 0; j < 25; j++){
            printf("args[%d][%d]", i, j);
        }
    }
}


void parse(char *input) { 
    char argArray[25][25];
    int numPipes = 0;
    int i = 0;
    int j = 0;
    char *tokenPtr = NULL;
    tokenPtr = strtok(input, delims);
    while(tokenPtr != NULL) {
        if(strcmp(tokenPtr, "|") == 0){ //is token a pipe?
            numPipes++;
            i++;
            j = 0;
        }
        else {
            argArray[i][j++] = *tokenPtr;
            printf("test1\n");
            tokenPtr = strtok(input, NULL);
            printf("test2\n");
        }
    }
    execute(*argArray, numPipes, i);
}

int main () {

    char path[MAX_PATH_LENGTH];
    char buf[BUF_LENGTH];
    char* strArray[BUF_LENGTH];

    while(1) {
      getcwd(path, MAX_PATH_LENGTH);
      printf("%s> ", path);
      fflush(stdout);
      fgets(buf, BUF_LENGTH, stdin);
      parse(buf);

      bzero(strArray, sizeof(strArray)); // clears array
   }
}

I was hoping someone could help me figure out why I am getting a segmentation fault on my code below. My user has inputted a line of text, which is passed to the parse function. The parse function should initialize a 2D array (I would ideally like to dynamically allocate the array, but for now I am making it an array of size [25][25]).

Starting at the beginning of input strtok() is called. If strtok() sees a pipe symbol, it should increase the count of pipes and go to the next row of the matrix. For example, if the user inputted foo bar | foo1 | foo2 bar1 foo2, the 2D array would look like:

array[][] = { foo, barr;
              foo1;
              foo2, bar1, foo2; }

Eventually I would like to pass this array to another function. However, If I actually input the above into my program, this is the result:

/home/ad/Documents> foo bar | foo1 | foo2 bar1 foo2
test1
Segmentation fault
ad@ad-laptop:~/Documents$

Thus, given where I put these debug statements, the problem is with saving the tokens? This is the first time I have worked with a 2D array so I am sure it is something wrong with my pointer logic. What can I do to fix this segmentation fault? Thanks for your time.

Code:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int MAX_PATH_LENGTH = 1024; //Maximum path length to display.
int BUF_LENGTH = 1024; // Length of buffer to store user input
char * delims = "|"; // Delimiters for tokenizing user input.
const int PIPE_READ = 0;
const int PIPE_WRITE = 1;

void execute(char *args, int numPipes, int numArgs){
    int i;
    int j;
    for(i = 0; i <= numArgs; i++){
        for(j = 0; j < 25; j++){
            printf("args[%d][%d]", i, j);
        }
    }
}


void parse(char *input) { 
    char argArray[25][25];
    int numPipes = 0;
    int i = 0;
    int j = 0;
    char *tokenPtr = NULL;
    tokenPtr = strtok(input, delims);
    while(tokenPtr != NULL) {
        if(strcmp(tokenPtr, "|") == 0){ //is token a pipe?
            numPipes++;
            i++;
            j = 0;
        }
        else {
            argArray[i][j++] = *tokenPtr;
            printf("test1\n");
            tokenPtr = strtok(input, NULL);
            printf("test2\n");
        }
    }
    execute(*argArray, numPipes, i);
}

int main () {

    char path[MAX_PATH_LENGTH];
    char buf[BUF_LENGTH];
    char* strArray[BUF_LENGTH];

    while(1) {
      getcwd(path, MAX_PATH_LENGTH);
      printf("%s> ", path);
      fflush(stdout);
      fgets(buf, BUF_LENGTH, stdin);
      parse(buf);

      bzero(strArray, sizeof(strArray)); // clears array
   }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

十二 2024-12-13 18:39:51

只有第一次调用 strtok 才应该接收输入。后续调用(在解析同一字符串时)应将 NULL 作为第一个参数。

Only the first call to strtok should receive the input. Subsequent calls (while parsing the same string) should have NULL as their first argument.

本王不退位尔等都是臣 2024-12-13 18:39:51

您误读了 strtok 的联机帮助页:

在应解析相同字符串的每个后续调用中,str 应为 NULL

你做了:tokenPtr = strtok(input, NULL);

You misread the manpage for strtok:

In each subsequent call that should parse the same string, str should be NULL.

And you did: tokenPtr = strtok(input, NULL);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文