【问题标题】:Parsing and Storing Tokens in C program在 C 程序中解析和存储令牌
【发布时间】:2016-02-28 22:43:20
【问题描述】:

所以对于我的问题,如果有人键入了某些内容,我会对其进行解析并将其存储到字符数组中。我用空格分隔用户键入的任何内容。然后我将这些标记存储到 char 数组中并打印出来。但是由于某种原因,在打印了第一个单词之后,一些乱码被打印出来了。 这是我的代码:

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

#define MAXLINE 80

int main(void) {
    char *args[MAXLINE / 2 + 1];
    char buf[MAXLINE / 2 + 1];
    scanf("%s", buf);
    int i;
    char *token;
    token = strtok(buf, " ");
    while (token != NULL) {
        args[i++] = token;
        token = strtok(NULL, " ");
    }

    //to print the array
    for (i = 0; i < strlen(*args); i++) {
        printf("%s\n" args[i]);
    }
    return 0;
}

【问题讨论】:

  • 请正确布局您的代码。您至少缺少一个}。此外,您在使用之前从未将 i 初始化为零,所以这可能是您的问题。最好将您的实际编译代码复制并粘贴到此处,而不是再次尝试输入它。没有名为buf 的变量。您显然声明了一个名为but
  • 您需要在第一次 strtok() 调用之后有 buf+=(token+1)。 +1 会将您带到分隔空间的右侧。
  • @ArifBurhan 不,您不必这样做,因为不再使用 buf
  • strlen(*args) 给出第一个字符串的长度。这显然不是你想要的。相反,此时i 已经包含存储在args 中的有效条目数,应该用作该循环的最大迭代次数。
  • @ArifBurhan 你不能有buf+=(token+1),因为buf是一个数组,这个表达式会产生编译错误。

标签: c arrays


【解决方案1】:

你的代码有几个问题:

  • char buf[MAXLINE / 2 + 1]; 似乎不正确,缓冲区大小应为 MAXLINE+1
  • 您读取了一个带有scanf("%s", buf) 的字符串:这样的字符串不会包含任何空格字符。尝试用 strtok 解析它总是会产生一个单一的标记,除了在文件末尾,你不测试它。您应该改用fgets()
  • i 未初始化,存储指向 args[i++] 的指针会调用未定义的行为。 i 应初始化为 0
  • 最后的循环条件不正确:i &lt; strlen(*args) 没有意义,您应该改用从0i 的不同索引和循环。

这是一个更正的版本:

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

#define MAXLINE 80

int main(void) {
    char *args[MAXLINE / 2];
    char buf[MAXLINE + 1];

    while (fgets(buf, sizeof buf, stdin)) {
        int i = 0, j;
        char *token = strtok(buf, " \t\n");
        while (token != NULL) {
            args[i++] = token;
            token = strtok(NULL, " \t\n");
        }
        //to print the array
        for (j = 0; j < i; j++) {
            printf("%s\n" args[j]);
        }
    }
    return 0;
}

【讨论】:

  • 我想这应该是评论,因为这不是主要问题的答案。
  • @StephCurry3093:您能否点击答案分数下方的灰色复选标记将其标记为已接受?
【解决方案2】:
  • 您必须在使用其值之前初始化i,否则您将调用未定义的行为
  • strlen(*argv) 不会给出令牌的数量。您必须保存该号码。
  • scanf() 会为你解析,所以你不需要strtok()

更正的代码:

#include <stdio.h>

#define MAXLINE 80

int main(void){
    char * args[MAXLINE/2 + 1];
    char buf [MAXLINE/2 + 1];
    int i = 0, num;
    char *token;
    token = buf;
    while(scanf("%s", token) == 1){
        args[i++] = token;
        token += strlen(token) + 1;
    }
    num = i;

    //to print the array
    for(i = 0; i < num;i++){
        printf("%s\n", args[i]);
    }
    return 0;
}

【讨论】:

  • 这段代码似乎只打印出第一个单词。例如,如果用户输入 Hello World,它只会打印出 Hello
  • 我能够通过使用 fgets(buf,MAXLINE,stdin) 而不是 scanf 来使其工作。但似乎有一个额外的空间在最后被打印出来
  • @StephCurry3093 谢谢你,很好。 fgets()读取的换行符不是“多余的空格”吗?
  • @StephCurry3093 strtok(XXXX, " "); :分隔符将 " " 更改为 " \n"
  • @MikeCAT:有趣的极简使用scanf 进行解析...但我没有看到一种简单的方法可以避免缓冲区溢出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多