【问题标题】:Tokenizing input from getline对来自 getline 的输入进行标记
【发布时间】:2013-03-02 19:34:10
【问题描述】:

我正在尝试使用 getline() 从键盘获取输入,将其存储在字符串中,对其进行标记,然后打印标记。当我运行它时,我在最后一次迭代(处理来自输入的最后一个标记的迭代)上得到一个 Segmentation Fault 错误。

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

////////////////////////
// Main Method        //
////////////////////////
void main() {
    system("clear");
    int ShInUse = 1; // Represents if shell is in use

    char curpath[1024];   // holds current path to print with prompt
    char *UserCommand = NULL;
    size_t combytes = 100;
    UserCommand = (char *) malloc(combytes);
    char *tok;

    // Main loop that shell uses //
    while (ShInUse == 1) {
        getcwd(curpath, sizeof(curpath)); // Store initial working dir
        printf("gash:%s>", curpath);   // print prompt

        getline(&UserCommand, &combytes, stdin);
        tok = strtok(UserCommand, " \n");   // Tokenize input
        if (tok == NULL ) {
            printf("Enter a command.\n");
        } else {
            // Exit command //
            if (strcmp(tok, "exit") == 0) {
                ShInUse = 0;
            } else {
                while (tok != NULL ) {
                    printf("You entered a command.\n");
                    printf("tok: %s\n", tok);
                    tok = strtok(NULL, " \n");
                }
            }
        }
    }
    free(UserCommand);
}

关于可能导致此问题的任何想法?目前,调试不是我的选择。

【问题讨论】:

  • 也许你忘记将 UserCommand 初始化为 NULL ?
  • 逐行注释代码以查看段错误发生的确切位置。
  • @wildplasser 感谢您的回复。我试过了,但它仍然没有用。我忘了包含我的字符串修饰符,我会将它们添加到我的帖子中。
  • @wildplasser 是的,我很清楚。我以前从未听说过,现在我真的很好奇。

标签: c string token tokenize strtok


【解决方案1】:

我用这个测试了你的代码:

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *UserCommand = NULL;
    size_t combytes = 100;
    UserCommand = (char *) malloc(combytes);
    char *tok;
    while(getline(&UserCommand, &combytes, stdin) != EOF)
    {
    tok = strtok(UserCommand, " \n");    // Tokenize input
    if (tok != NULL) {
        while(tok != NULL) {
        printf("%s\n", tok);
        tok = strtok(NULL, " \n");
        }
    }
    }
    return 0;
}

它适用于我所做的所有测试 - 包括将源文件作为输入传递,编写很长的行等等。

所以我的结论是,您的代码中可能存在 ELSE 段错误。

【讨论】:

  • +1 在阅读了getline() 上的文档后,这段代码似乎非常合理(尽管不需要if(tok != NULL))。我认为你是对的。问题可能出在其他地方。
  • 嗨,垫子! ..为什么 getline(&amp;UserCommand, &amp;combytes, stdin) 在 While 循环中。我了解 OP 需要 getline() 一次。我在哪里错过
  • 是的,我“按原样”采用现有代码,只是为了避免“删除/添加”影响其行为的东西 - 尽管我确实发现 if 是“不需要”。
  • 我添加了while,这样我就不必为每一行输入重新启动程序 - 特别是这样我可以为它提供一些比我懒得写的更长/更实质性的输入手工。
  • 这是一个POSIX函数,所以在Windows系统中可能不存在。我在 Linux 系统上使用 gcc 4.6.3。
【解决方案2】:

也不是答案,只是编程风格的另一种选择:

每当我有一个像你这样的标记循环时,我更喜欢这样构造它们:

for( tok = strtok( UserCommand, " \n" );
     tok != NULL;
     tok = strtok( NULL, " \n" ) )
{
   printf( "%s\n", tok );
}

这使两个strtok() 调用紧密结合在一起,并且只需要编写一次NULL 测试。你的方法很好,这只是另一种选择。祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 2015-06-18
    • 2018-08-14
    • 2020-10-29
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多