分割一个字符串并打印出每个单词

5

我被分配了一个任务,要求用户输入一行文本。程序在遇到逗号时将每个单词分开。完成后,程序会将每个单词打印在新的一行上。例如:

请输入一行文本:Mary,had,a,little,lamb

Mary
had
a
little
lamb

这项任务不允许使用 strtok(),因此我不能使用它。我可以使用以下函数:

printf()fprintf()malloc()calloc()realloc()free()fgets()snprintf()strncpy()strncat()strncmp()strdup()strlen()strchr()

目前为止,我已经完成了:

   int i;

   char line[256];
   char *next;

   printf("Enter the string\n");
   fgets(line, 256, stdin);

   char *curr = line;

   while ((next = strchr(curr, ',')) != NULL) {
      curr = next + 1;
   }

   int len = strlen(curr);

   for (i = 0; i < len; i++) {
      printf("%c", curr[i]);
   }

截至目前,如果我的字符串是:Mary,had,a,little,lamb,那么它只会打印出:

lamb

。有什么建议吗?

1
顺便说一句:有时不允许使用某个函数是件好事。远离 strtok - Jean-François Fabre
好的建议,要注意 strtok() 会将任何逗号序列视为单个逗号。此外,要避免使用 strncpy() - chqrlie
你应该更加强调“程序在遇到逗号时分割每个单词”,字符串的打印只是为了检查它是否工作正常,但真正困难的任务是使用reallocstrdup创建一个动态字符串数组。你离解决方案还有很长的路要走(而且所有的答案都是错误的,我已经删除了我的简单答案)。 - Jean-François Fabre
@chqrlie 至少原帖的作者可以从你的回答开始并加以改进。 - Jean-François Fabre
1
@Karth:祝您享受新的投票特权。现在您可以进行“点赞”操作,同时也可以接受答案(如果您认为其他答案有帮助,也可以进行点赞,但这不是必须的)。 - Jean-François Fabre
显示剩余3条评论
2个回答

4

很遗憾,他们没有列出最适合此任务的函数:strcspn()。您可以使用已发布的strchr(),但是打印结果时会有问题。您可以使用%.*s格式说明符来打印子字符串:

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

int main(void) {
    char line[256];

    printf("Enter the string\n");
    if (fgets(line, 256, stdin)) {
        char *curr = line;
        char *next;

        while ((next = strchr(curr, ',')) != NULL) {
            /* found a separator: print the word between curr and next */
            printf("%.*s\n", (int)(next - curr), curr);
            curr = next + 1;
        }
        /* print the last word */
        printf("%s", curr);
    }
    return 0;
}

如果您不能使用这个比较高级的printf功能,您可以通过以下方式修改字符串:

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

int main(void) {
    char line[256];

    printf("Enter the string\n");
    if (fgets(line, 256, stdin)) {
        char *curr = line;
        char *next;

        while ((next = strchr(curr, ',')) != NULL) {
            /* found a separator: replace it with '\0' */
            *next++ = '\0';
            printf("%s\n", curr);
            curr = next;
        }
        /* print the last word */
        printf("%s", curr);
    }
    return 0;
}

另外请注意,您可以使用更简单的解决方案,甚至不需要缓冲区,而是使用未列出的 getchar()putchar() 函数:
#include <stdio.h>

int main(void) {
    int c;

    while ((c = getchar()) != EOF) {
        putchar(c == ',' ? '\n' : c);
        if (c == '\n')
            break;
    }
    return 0;
}

编辑:如果两个逗号挨在一起表示它们是一个单词中的普通逗号,请尝试以下方法:

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

int main(void) {
    char line[256];

    printf("Enter the string\n");
    if (fgets(line, 256, stdin)) {
        char *curr = line;
        char *next;

        while ((next = strchr(curr, ',')) != NULL) {
            /* found a separator: print the word between curr and next */
            if (next[1] == ',') {
                next++;
                printf("%.*s", (int)(next - curr), curr);
            } else {
                printf("%.*s\n", (int)(next - curr), curr);
            }
            curr = next + 1;
        }
        /* print the last word */
        printf("%s", curr);
    }
    return 0;
}

编辑 2 鉴于您需要将字符串拆分为指针数组,因此代码会稍微复杂一些。该数组不需要分配,因为单词数受输入缓冲区大小的限制:

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

int main(void) {
    char line[256];
    char *array[256];
    int i, n;

    printf("Enter the string\n");
    if (fgets(line, 256, stdin)) {
        char *p = strchr(line, '\n');
        if (p != NULL) {
            *p = '\0';   /* strip the newline if any */
        }
        /* split the line into an array of words */
        n = 0;
        array[n++] = p = line;
        while ((p = strchr(p, ',')) != NULL) {
            *p++ = '\0';
            array[n++] = p;
        }
        /* print the words */
        for (i = 0; i < n; i++) {
            printf("%s\n", array[i]);
        }
    }
    return 0;
}

非常感谢您的输入!您的第一个解决方案非常好!如果字符串中包含相邻的逗号,并且我想打印出第二个逗号怎么办?例如:12345,1234,,,123,12,1,, 它会打印出 "12345 1234 , 123 12 1 ," - Karth
@Karth:如果字符串中有两个逗号相邻,那么就意味着有一个空单词,从而产生了一个空行。如果你想让它表示一个字面上的逗号,那么代码可以被修改为这个目的,如所发布的。 - chqrlie

-1
在这个循环中,您将curr向最后一个','移动。
   while ((next = strchr(curr, ',')) != NULL) {
      curr = next + 1;
   }

在找到 ',' 的同时进行操作。然后,当然,只剩下最后一个逗号后面的符号。 您应该检查当前符号是否为逗号,如果不是,则将其放入临时字符串中。一旦遇到逗号 - 打印该临时字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接