【问题标题】:How to get line from stdin and split it to tokens?如何从标准输入获取线路并将其拆分为令牌?
【发布时间】:2018-01-08 16:03:23
【问题描述】:

我正在尝试编写 RPN 计算器,但我一直在努力从用户那里获取参数。我想做的是:取整行,将其拆分为令牌并将其放入数组中。我有类似下面的东西,但它只工作一次。在第二个 while 循环中执行 line,但 arr==NULL

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

#define MAX_str 100

char* getLine(){
  char* line = malloc(MAX_str*sizeof(char*));
  return fgets(line, MAX_str,stdin);
}

char** toArray(char* line){
  int i=0;
  char** array= malloc(MAX_str*sizeof(char*));
  array[i] = strtok(line," \t");
  while(array[i]!=NULL){
    array[++i] = strtok(NULL,"");
  }
  return array;
}

int main(){
  char* linia;
  char** arr;
  int i=0,end=0;

  while(!end){
    linia=getLine();
    arr = toArray(linia);
    while(arr[i]!=NULL){
      printf("%s\n",arr[i]);
      i++;
    }
  free(linia);
  free(arr);
  }
}

其次,strtok 仅在两个标记上拆分,例如

>1 2 3

给予:

>1
>2 3

【问题讨论】:

  • 除了乱七八糟的代码之外,代码创建了很多(sizeof(char*))、少数(sizeof(line))的分配,并且错过了释放,你想告诉 each 调用到strdup() 做同样的事情,即通过" \t" 标记化。
  • moorzyn,好奇:为什么代码在char** array = malloc(MAX_str*sizeof(line)); 中使用sizeof(line)
  • 提示:"" in array[++i] = strtok(NULL,""); 是一个非常小的令牌列表。
  • @allk 回复:to few (sizeof(line))。这看起来不寻常,但malloc(MAX_str*sizeof(line)); 似乎并不少见。你的想法?
  • 好吧,我刚开始学习 C,所以这就是它看起来如此糟糕的原因。 @chux 我的意思是char*,而不是line。我不知道为什么我把它放在那里。我已经编辑了代码。

标签: c string


【解决方案1】:

代码的主要问题是对strtok() 的后续调用使用空标记字符串。根据需要将字符添加到第二个令牌列表

// array[++i] = strtok(NULL,"");
array[++i] = strtok(NULL," \t\n");

getLine()的改进思路:先读后分配。

char* getLine(){
  char buf[MAX_str];
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    return NULL;
  }
  return strdup(buf);
}

strdup() 很常见,尽管不在 C 标准中。 Code example.

【讨论】:

    【解决方案2】:

    好吧,愚蠢会花费时间...我忘记在 main() 中循环后重置 i...

    这段代码更好吗?我希望arr 成为char 指针的表,数量为MAX_str。声明得好吗?使用malloc 会像上面的答案那样初始化吗?为了防止array 溢出,我将比较iMAX_str 的值。可以吗?

    #define MAX_str 100
    
    char* getLine(){
      char buf[MAX_str];
      if (fgets(buf, sizeof buf, stdin) == NULL) {
        return NULL;
      }
      return strdup(buf);
    }
    
    int toArray(char* line, char* array[MAX_str]){
      int i=0;
      array[i] = strtok(line," \t\n");
      while(array[i]!=NULL){
        array[++i] = strtok(NULL," \t\n");
      }
      return i;
    }
    
    int main(){
      char* linia;
      char* arr[MAX_str];
      int i=0,end=0;
    
      while(!end){
        linia=getLine();
        assert(linia!=NULL);
    
        toArray(linia,arr);
        assert(arr!=NULL);
    
        while(arr[i]!=NULL){
          printf("%s\n",arr[i]);
          i++;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-04
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      相关资源
      最近更新 更多