2014-11-06 51 views
0

我正在尝试编写一个接受MadLib大纲作为.txt文件的C程序。该程序然后要求用户输入一系列短语放入Madlib中。我有这部分完整。但是,我希望能够将用户输入的MadLib短语&插入到早先打开的.txt文件中。然后,我希望能够允许用户将完成的MadLib保存在不同的.txt文件名下。 MadLib大纲在其中放置了关键字,表示用户输入的单词应该放在哪里。 (见下文)。带重定向输入和输出的MadLib C程序

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

马德利布大纲.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>. 
+1

您可以从'fgets'开始从您的文件中读取一行,然后使用'strchr'来查找尖括号。然后将文本复制出来,并将尖括号中的文本替换为您阅读的文字。我不确定除了编写程序来完成您所描述的内容之外,还有别的方法可以回答您的问题。如果您有更具体的问题,请告诉我。 – yellowantphil 2014-11-06 01:15:50

回答

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

您可以通过用空格替换''(如果存在)中的短划线,然后在提示中使用修改的字符串,使用户输入的提示更加紧凑吗? – 2014-11-06 17:19:27

+0

感谢您的帮助! – Josh 2014-11-06 20:27:21

0

这是另一种答案,只是没有查找和替换(因为编写解析器不上狡猾的输入突破是)。

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

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

代码...

#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]. 
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 

但是也许你别无选择。