具有重定向输入的MadLib C程序&产量

时间:2014-11-06 00:59:58

标签: c

我正在尝试编写一个接受MadLib大纲作为.txt文件的C程序。程序然后要求用户输入一系列要放入Madlib的短语。我完成了这一部分。但是,我希望能够使用用户输入的MadLib短语&将它们插入之前打开的.txt文件中。然后,我希望能够允许用户将完成的MadLib保存在不同的.txt文件名下。 MadLib大纲中放置了关键字,表示用户输入的单词应该去的位置。 (见下文)。

我应该如何用用户输入的短语替换这些占位符?

MadLib Outline .txt文件:

One of the most <adjective> characters in fiction is named
"Tarzan of the <plural-noun>." Tarzan was raised by a/an
<noun> and lives in the <adjective> jungle in the
heart of darkest <place>. He spends most of his time
eating <plural-noun> and swinging from tree to <noun>.
Whenever he gets angry, he beats on his chest and says,
"<funny-noise>!" This is his war cry. Tarzan always dresses in
<adjective> shorts made from the skin of a/an <noun>
and his best friend is a/an <adjective> chimpanzee named
Cheetah. He is supposed to be able to speak to elephants and 
<plural-noun>. In the movies, Tarzan is played by <person's-name>.

3 个答案:

答案 0 :(得分:1)

这使用fscanf从文件中读取。它会提示输入每种类型的单词,并将最终文本输出到输出文件。您可以将文件名作为命令行的一部分提供,如program inputfile outputfile中所示。如果文件名不在命令行中,则madlib.txt的默认文件名将用于输入文件,madlib-out.txt将用于输出文件。

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

int main( int argc, char *argv[]) {
    FILE *fpIn = NULL;
    FILE *fpOut = NULL;
    char cFileIn[100] = { 0};
    char cFileOut[100] = { 0};
    char cIn[500] = { 0};
    char cType[100] = { 0};
    char cWord[100] = { 0};
    char cCh[2] = { 0};
    char *pDash = NULL;

    if ( argc == 3) { // use command line arguments if present
        strcpy ( cFileIn, argv[1]);
        strcpy ( cFileOut, argv[2]);
    }
    else { // default file names
        strcpy ( cFileIn, "madlib.txt");
        strcpy ( cFileOut, "madlib-out.txt");
    }


    fpIn = fopen ( cFileIn, "r");
    if ( fpIn == NULL) {
        printf ( "could not open input file %s\n", cFileIn);
        return 1; // fopen failed
    }

    fpOut = fopen ( cFileOut, "w");
    if ( fpOut == NULL) {
        fclose ( fpIn); // close the input file
        printf ( "could not open output file %s\n", cFileOut);
        return 1; // fopen failed
    }

    // scan up to 499 characters stopping at <
    while ( fscanf ( fpIn, "%499[^<]", cIn) == 1) {
        // scan one character, should be the <
        if ( ( fscanf ( fpIn, "%1s", cCh)) == 1) {
            if ( cCh[0] == '<') {
                fprintf ( fpOut, "%s", cIn); // print to the output file
                // scan the type of word needed
                if ( ( fscanf ( fpIn, "%99[^>]", cType)) == 1) {
                    if ( ( pDash = strstr ( cType, "-"))) {
                        *pDash = ' '; // remove - if present
                    }
                    // for each type, prompt and scan
                    printf ( "Enter a(n) %s\n", cType);
                    // skip whitespace then scan up to 99 characters stopping at newline
                    scanf ( " %99[^\n]", cWord);
                    fprintf ( fpOut, "%s", cWord); // print to the output file
                }
                if ( ( fscanf ( fpIn, "%1[>]", cCh)) == 1) {
                    ; // scan the >
                }
            }
        }
    }

    fclose ( fpIn); // close files
    fclose ( fpOut);
    return 0;
}

答案 1 :(得分:0)

这是一个替代答案,只是找到并替换(因为编写一个不会在狡猾的输入上打破的解析器 hard )。

它从用户读取值,使用strstr函数在文本中查找相关标记并替换用户值(如果标记出现多次,则重复)。替代涉及:

  1. 将所有内容保存在标记之前。
  2. 将标记后面的内容复制到另一个字符串。
  3. 插入用户值。
  4. 复制其他字符串的内容。
  5. 代码......

    #include <stdio.h>
    #include <string.h>
    
    #define BUFSIZE 65535
    #define MAXSTR 100 
    
    int main(int argc, char ** argv) {
    
        char string_dict[4][3][MAXSTR]  = 
             { {"What is your name? ", "[name]", ""},
               {"What country do you live in? ", "[country]", ""},
               {"What is your age? ", "[age]", ""},
               {"What is your favourite food?", "[favourite food]", ""} };
        int arr_len = sizeof(string_dict)/sizeof(*string_dict);
    
        char buf1[BUFSIZE];
        char buf2[BUFSIZE];
        char currtag[MAXSTR];
        char *pos = buf1;
        FILE *fd;
        int i;  
    
        buf2[0] = '\0';
    
        fd = fopen("input_file.txt", "r");
        fread(buf1, BUFSIZE-1, 1, fd); 
        fclose(fd);
    
        for (i = 0; i < arr_len; i++) {
            printf("%s", string_dict[i][0]);
            fgets(string_dict[i][2], MAXSTR, stdin);
            string_dict[i][2][strlen(string_dict[i][2])-1] = '\0';
            while (pos = strstr(buf1, string_dict[i][1])) {
                *pos = '\0';
                strcat(buf2, pos + strlen(string_dict[i][1]));
                strcat(pos, string_dict[i][2]);
                pos += strlen(string_dict[i][2]);
                strcat(pos, buf2);
                pos = buf1; 
                buf2[0] = '\0';
            }
    
        } 
    
        fd = fopen("output_file.txt", "w");
        fputs(buf1, fd);
        fclose(fd);
    }
    

    这非常强大,但肯定不是万无一失的。问题:如果在提示输入您的姓名时输入字符串[name]会发生什么?此外,您可以非常轻松地超出输入缓冲区。

    input_file.txt看起来像:

    My name is [name], and I am [age] years old.  
    I live in [country] and my favourite nosh 
    is [favourite food].
    

答案 2 :(得分:0)

既然已经有了真正的答案,那么只需要一个快速的补充说明,如果你有一个选择,你可以更容易地做到这一点,如果你没有使用C. Python将使它变得微不足道......

infile = open("input_file.txt", "r")
template = infile.read()
infile.close()

questions = [ ["What is your name? ", "[name]"],
              ["How old are you? ", "[age]"],
              ["Which country are you from? ", "[country]"],
              ["What is your favourite food? ", "[favourite food]" ] ]

for q in questions:
    template = template.replace(q[1], input(q[0]))

outfile = open("output_file.txt", "w")
outfile.write(template)
outfile.close

但也许你别无选择。