繁体   English   中英

使用 get() 按空格分隔字符串

[英]Separating Strings by Spaces Using gets()

今天我有一个关于使用 get() 函数用空格分隔字符串的问题。 我有一个接收用户输入并按字母顺序排序的程序。 我的问题出在 main 函数中,我在其中接收了字符串。 如果遇到行首的单个点或遇到 EOF,程序应停止读取用户输入并返回已排序的链表。 我使用gets()是因为它是项目要求的一部分,但是我的问题是,当我使用gets时,它只是将整个字符串发送到我的排序函数中,而不是用空格分隔。 我的问题是:有没有办法用空格分隔由 get() 捕获的字符串? 请在下面找到我的实现以及示例输入。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//defining node structure
typedef struct node
{
    char data[255];//can store upto 255 characters
    struct node *next;
}Node;
Node *head=NULL;//initially linked list is empty
//method to insert in sorted order
void insert_dictionary_order(char *a)
{
    Node *n = (Node*)malloc(sizeof(Node));//creating new node
    strcpy(n->data,a);//reading data
    n->next=NULL;
    Node *temp=head,*prev=NULL;
    if(temp==NULL)
    {
        head=n;
    }
    else
    {//inserting in right position
        while(temp!=NULL)
        {
            if(0<strcmp(temp->data,a))
                break;
            prev=temp;
            temp=temp->next;
        }
        if(prev==NULL)
        {
            n->next=head;
            head=n;
        }
        else
        {
            n->next=prev->next;
            prev->next=n;
        }
    }
}
//method to print all words in list
void print_list()
{
    Node *temp=head;
    while(temp!=NULL)
    {
        printf("%s ",temp->data);
        temp=temp->next;
    }
    printf("\n");
}
int main()
{
    printf("Enter words seperated by spaces:(. or EOF to stop):\n");

    do
    {
        char s[255];
        //scanf("%s",s);
        gets(s);
        if(strcmp(s,".")==0  || strcmp(s,"EOF")==0)
        {
            insert_dictionary_order(s);//adding to list
            break;
        }

        else
        {
            while((strcmp(s,'\0') !=0) && (strcmp(s,' ') !=0))
            {
                insert_dictionary_order(s);//adding to list
            }
        }

    }
    while(1);
    //printf("The string: %s\n", s);
    //now printing list
     print_list();
    return 0;
}
This is a sample text.
The file will be terminated by a single dot: .
The program continues processing the lines because the dot (.)
did not appear at the beginning.
. even though this line starts with a dot, it is not a single dot.
The program stops processing lines right here.
.
You won't be able to feed any more lines to the program.

编辑:也允许使用 sscanf,但不允许使用 scanf

首先,一些其他的东西。

不要使用gets 让我们使用fgets 一切都会一样,只是更安全。

您不应该使用全局head 应该将指向字典的指针传递给函数。 我不会在这里纠正。

strcpy(n->data,a)是不安全的,你不知道a有多大。 与其使用浪费的静态缓冲区,不如存储一个char *并使用strdup复制和分配您需要的内存。

typedef struct node
{
    char *data;
    struct node *next;
} Node;

Node *n = malloc(sizeof(Node));
n->data = strdup(word);

strcmp比较整个字符串,因此strcmp(s,".")==0仅当s恰好是单个点时才匹配。 strcmp(s,'\\0')strcmp(s,' ')都不起作用,因为它们是单个字符,而不是字符串。 编译器可以警告您,但不幸的是,默认情况下它们是关闭的。 打开它们。

strcmp(s,"EOF")==0正在寻找字符串EOF 这不是您检测文件结尾的方式。 相反,请使用feof(stdin)检查您是否已到达文件末尾。

但是,检查 EOF 是不必要的,并且会导致错误。 正常的fgets循环是这样的:

// Allocate a large buffer and reuse it.
char line[BUFSIZ];

// `fgets` returns NULL on error or end-of-file, which is false.
while( fgets(line, sizeof(line), stdin) ) {
    // Put processing the line into a function to keep things simple.
    if( add_line(line) ) {
        // We saw a dot, exit the loop.
        break;
    }
}

有没有办法用空格分隔由 get() 捕获的字符串?

通过读取的行,我们可以使用strtok (STRing TOKenize) 拆分行。 strtok是一个有趣的函数,它有自己的内部状态。 第一次调用它时,它会记住它被调用的内容。 然后用NULL调用它以继续在字符串中查找更多标记。

strtok工作原理是用空字节替换分隔符,这样您就可以在不复制的情况下读取每个标记。 它确实修改了原始字符串,但我们不关心是否修改了line

bool add_line(char *line) {
    char *token;
    for(
      token = strtok(line, " \t\n");  // split on spaces or tabs
      token;                          // stop when there's nothing more
      token = strtok(NULL, " \t\n")   // continue splitting line
    ) {
        printf("token: %s\n", token);
        if( strcmp(token, ".") == 0 ) {
            // We saw a lone dot, stop reading.
            return true;
        }

        insert_dictionary_order(token);
    }

    // Continue reading.
    return false;
}

在空间和换行符上拆分很重要,否则换行符将成为每个令牌的一部分。 这会弄乱字典,而且行尾的点将是".\\n"并且不匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM