Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用scanf读取文件中的每个单词。_C_Scanf - Fatal编程技术网

如何使用scanf读取文件中的每个单词。

如何使用scanf读取文件中的每个单词。,c,scanf,C,Scanf,在c代码中。我有一个输入文件(在中调用),它是一个mad库,格式为“我真的有眼睛”(在中没有空格),我想编写一个bool函数,它使用scanf读取每个单词,并返回true如果调用者中的单词以“开头,word的大小必须足以容纳文本中最大的单词(+3个字符,2个代表和nul termanting字符。您应该将单词的最大长度作为参数传递给istoken,但由于您使用的是扫描,因此必须硬编码字段宽度修饰符以保护数组边界。(这是建议使用fgets而不是scanf——但您必须使用scanf)的原因之一。不要

在c代码中。我有一个输入文件(在中调用),它是一个mad库,格式为“我真的有<形容词>眼睛”(在中没有空格),我想编写一个bool函数,它使用scanf读取每个单词,并返回true如果调用者中的单词以“开头,
word
的大小必须足以容纳文本中最大的单词(+3个字符,2个代表
和nul termanting字符。您应该将
单词的最大长度作为参数传递给
istoken
,但由于您使用的是
扫描
,因此必须硬编码字段宽度修饰符以保护数组边界。(这是建议使用
fgets
而不是
scanf
——但您必须使用
scanf
)的原因之一。不要在调用者中略过
word
的缓冲区大小。以下内容在调用者中应该足够了(对您来说可能是
main()
):

无需使用
first
firstindex
。要检查字符串中的第一个字符,只需取消对指针的引用。这样,只需执行以下操作:

/* istoken = returns true if word is a token */
bool istoken (char *word) {

    while (scanf("%1023s", word) == 1)  /* did a valid read take place? */
        if (*word == '<')               /* is 1st char '<' ? */
            return true;                /* return true */

    return false;                       /* out of words, return false */
}
示例使用/输出

$ echo "my dog has <too> many fleas." | ./bin/scanftoken
found token: '<too>'
$ ./bin/scanftoken
found token: '<too>'

$ cat tokenfile.txt
<too>
这通常是您希望避免的。在程序设计中,您希望(作为目标)将实现(程序的功能、计算等)与输入/输出分开。这使得您的代码在被多个希望输出
printf(“标记为:%s\n”,word);

虽然有点不常见,但是如果调用方随后使用
word
中的
istoken
返回值来确定如何处理令牌,则您的
istoken
函数定位令牌并返回
true/false
更有意义。如果您只是从
intoken内部打印它,如果找到令牌,则不使用return在调用者中,那么为什么要声明它为
bool
呢?如果您不使用return,您也可以将它声明为
void

就像我说的,这是(一个目标)。只要代码是有效的,就可以以任何方式考虑代码。在
istoken
中使用
printf
对于临时调试目的也是完全有效的。(事实上,这是您拥有的最有用的调试工具之一,只需在程序的逻辑路径中撒上临时的
printf
语句,就可以找到代码按预期工作的位置以及可以说“火车从轨道上掉下来”的位置


文件I/O示例

好的,我们终于开始解决这个
'XY'
问题了。因为,正如我现在所理解的,你有一个文件中的文本(我使用了
“myfile.txt”
作为输入),你想在
istoken
中读取你的输入文件,并将
word
true/false
返回到
main()
如果
true
则将令牌写入输出文件(我之前在输出文件中使用了“tokenfile.txt”),然后需要使用
main()
中的
fopen
打开输入文件和输出文件,如下所示:

    FILE *ifp = fopen ("myfile.txt", "r"),      /* infile pointer */
         *ofp = fopen ("tokenfile.txt", "w");   /* outfile pointer */
#include <stdio.h>
#include <stdbool.h>

#define MAXC 1024

/* istoken = returns true if word is a token */
bool istoken (FILE *ifp, char *word) {

    while (fscanf(ifp, "%1023s", word) == 1)    /* valid read take place? */
        if (*word == '<')                       /* is 1st char '<' ? */
            return true;                        /* return true */

    return false;                               /* out of words */
}

int main (void) {

    char word[MAXC] = "";
    FILE *ifp = fopen ("myfile.txt", "r"),      /* infile pointer */
         *ofp = fopen ("tokenfile.txt", "w");   /* outfile pointer */

    if (ifp == NULL) {  /* validate input open for reading */
        perror ("fopen-myfile.txt");
        return 1;
    }

    if (ofp == NULL) {  /* validate output open for writing */
        perror ("fopen-tokenfile.txt");
        return 1;
    }

    if (istoken (ifp, word)) {  /* call istoken passing open ifp */
        printf ("found token: '%s'\n", word);   /* output token */
        fprintf (ofp, "%s\n", word); /* write token to outfile */
    }
    else
        fprintf (stderr, "error: no token found.\n");

    fclose (ifp);           /* close infile pointer */

    if (fclose(ofp) == EOF) /* validate "close-after-write" */
        perror ("stream error on outfile stream close");

    return 0;
}
(我不是那么有创意,我只是用
ifp
作为输入文件指针,用
ofp
作为输出文件指针)

无论何时打开文件,在尝试读取或写入文件之前,必须验证文件是否已实际打开以进行读取或写入(例如,
fopen
成功)。例如:

    if (ifp == NULL) {  /* validate input open for reading */
        perror ("fopen-myfile.txt");
        return 1;
    }

    if (ofp == NULL) {  /* validate output open for writing */
        perror ("fopen-tokenfile.txt");
        return 1;
    }
/* istoken = returns true if word is a token */
bool istoken (FILE *ifp, char *word) {

    while (fscanf(ifp, "%1023s", word) == 1)    /* valid read take place? */
        if (*word == '<')                       /* is 1st char '<' ? */
            return true;                        /* return true */

    return false;                               /* out of words */
}
现在,当两个文件都打开时,您可以调用
istoken
并从
ifp
读取。但是,这需要修改
istoken
以获取
FILE*
参数,以便与
fscanf
一起使用,而不是使用
scanf
。例如:

    if (ifp == NULL) {  /* validate input open for reading */
        perror ("fopen-myfile.txt");
        return 1;
    }

    if (ofp == NULL) {  /* validate output open for writing */
        perror ("fopen-tokenfile.txt");
        return 1;
    }
/* istoken = returns true if word is a token */
bool istoken (FILE *ifp, char *word) {

    while (fscanf(ifp, "%1023s", word) == 1)    /* valid read take place? */
        if (*word == '<')                       /* is 1st char '<' ? */
            return true;                        /* return true */

    return false;                               /* out of words */
}
最后,您必须
fclose
您打开的文件。但是您写入的文件有一个扭曲。您应该验证
fclose
,以确保在
ofp
上不会发生流错误,否则可能不会被捕获。例如

    fclose (ifp);           /* close infile pointer */

    if (fclose(ofp) == EOF) /* validate "close-after-write" */
        perror ("stream error on outfile stream close");
总而言之,您可以执行以下操作:

    FILE *ifp = fopen ("myfile.txt", "r"),      /* infile pointer */
         *ofp = fopen ("tokenfile.txt", "w");   /* outfile pointer */
#include <stdio.h>
#include <stdbool.h>

#define MAXC 1024

/* istoken = returns true if word is a token */
bool istoken (FILE *ifp, char *word) {

    while (fscanf(ifp, "%1023s", word) == 1)    /* valid read take place? */
        if (*word == '<')                       /* is 1st char '<' ? */
            return true;                        /* return true */

    return false;                               /* out of words */
}

int main (void) {

    char word[MAXC] = "";
    FILE *ifp = fopen ("myfile.txt", "r"),      /* infile pointer */
         *ofp = fopen ("tokenfile.txt", "w");   /* outfile pointer */

    if (ifp == NULL) {  /* validate input open for reading */
        perror ("fopen-myfile.txt");
        return 1;
    }

    if (ofp == NULL) {  /* validate output open for writing */
        perror ("fopen-tokenfile.txt");
        return 1;
    }

    if (istoken (ifp, word)) {  /* call istoken passing open ifp */
        printf ("found token: '%s'\n", word);   /* output token */
        fprintf (ofp, "%s\n", word); /* write token to outfile */
    }
    else
        fprintf (stderr, "error: no token found.\n");

    fclose (ifp);           /* close infile pointer */

    if (fclose(ofp) == EOF) /* validate "close-after-write" */
        perror ("stream error on outfile stream close");

    return 0;
}
#包括
#包括
#定义maxc1024
/*istoken=如果word是标记,则返回true*/
bool-istoken(文件*ifp,字符*word){
当(fscanf(ifp,“%1023s”,word)==1)/*发生有效读取时*/

如果调用者中有(*word==',
word
的大小必须足以容纳文本中最大的单词(+3个字符,2个代表
和nul termanting字符。您应该将
单词的最大长度作为参数传递给
istoken
,但由于您使用的是
扫描
,因此必须硬编码字段宽度修饰符以保护数组边界。(这是建议使用
fgets
而不是
scanf
——但您必须使用
scanf
)的原因之一。不要在调用者中略过
word
的缓冲区大小。以下内容在调用者中应该足够了(对您来说可能是
main()
):

无需使用
first
firstindex
。要检查字符串中的第一个字符,只需取消对指针的引用。这样,只需执行以下操作:

/* istoken = returns true if word is a token */
bool istoken (char *word) {

    while (scanf("%1023s", word) == 1)  /* did a valid read take place? */
        if (*word == '<')               /* is 1st char '<' ? */
            return true;                /* return true */

    return false;                       /* out of words, return false */
}
示例使用/输出

$ echo "my dog has <too> many fleas." | ./bin/scanftoken
found token: '<too>'
$ ./bin/scanftoken
found token: '<too>'

$ cat tokenfile.txt
<too>
这通常是您希望避免的。在程序设计中,您希望(作为目标)将实现(程序的功能、计算等)与输入/输出分开。这使得您的代码在被多个希望输出
printf(“标记为:%s\n”,word);

虽然有点不常见,但是如果调用方随后使用该返回来确定如何处理
word
中的令牌,则查找令牌并返回
true/false
istoken
函数更有意义