在两个给定字符之间打印一个数组

时间:2019-01-14 23:06:59

标签: c

我有一个文件,我需要在两个给定字符z1和z2之间打印该部分。我知道第一个之后如何打印,但是我不知道在遇到z2时如何停止打印。

注意:wtf函数是从练习中编写的。

我尝试过if(niz == z2) {break;},但似乎不起作用

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

void wtf() {
    FILE *f = fopen("podatoci.txt", "w");
    char c;
    while((c = getchar()) != '#') {
        fputc(c, f);
    }
    fclose(f);
}

int main() {
    wtf();
    getchar();
    char c, z1, z2;
    scanf("%c %c", &z1, &z2);
    FILE *fo = fopen("podatoci.txt", "r");
    char niz[80];
    char *a;
    while(fgets(niz, 80, fo) != NULL) {
        printf("%s", strchr(niz, z1) + 1);

    }   
    fclose(fo);

    return 0;
}

我需要数组在遇到z2时停止打印。

1 个答案:

答案 0 :(得分:1)

将用户输入的z1z2之间的字符(如果有)定位在从文件读取的缓冲区中的关键是验证:

  • 缓冲区中存在z1(保存位置供以后使用);
  • z2存在于缓冲区的其余部分中(保存位置供以后使用);最后
  • z2不是缓冲区中z1之后的下一个字符-意味着z1z2之间至少存在1个有效字符。

虽然您可以使用fgets(我建议这样做),但是为了简化示例,让我们使用POSIX getline以避免必须手动分配/重新分配以确保读取完整的行(无论如何)的长度)。如果您知道预先要从文件中读取的最大字符数,则只需使用固定大小的缓冲区并使用您选择的输入功能即可。

将一行中的所有字符读入缓冲区后,只需在缓冲区中找到z1z2即可。 strchr将在缓冲区中搜索是否存在每个字符,如果找到了该字符,则返回一个指针(如果找不到该字符,则返回NULL)。在每种情况下,您只需保存strchr返回的指针,这将为您留下一个指针(前1个字符)和(后1个字符)字符 之间 z1z2

(提示:如果您增加p1,它将指向您想要的第一个字符)

然后,只需分配存储空间以容纳p1p2之间的字符,然后使用memcpy将字符复制到新存储空间(记住为 nul -终止结果缓冲区),然后再输出结果。同样,如果使用固定大小的缓冲区保存从文件读取的行,则第二个大小相等的缓冲区足以保存z1z2之间的字符。

将其完全放在一起,您可以执行以下操作:

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

int main (int argc, char **argv) {

    char z1, z2,        /* user input characters */
        *p1, *p2,       /* pointers to bracket z1, z2 in buf */
        *buf = NULL,    /* buffer to hold line read from file */
        *btwn = NULL;   /* buffer to hold chars between z1, z2 */
    size_t n = 0;       /* allocation size (0 - getline decides) */
    FILE *fp = NULL; 

    if (argc < 2 ) {    /* validate filename provided as argument */
        fprintf (stderr, "error: insufficient input, usage: %s <file>\n",
                argv[0]);
        return 1;
    }
    fp = fopen (argv[1], "r");      /* open file */

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }
    /* prompt, read/validate 2 non-whitespace characters entered */
    fputs ("enter beginning and ending characters: ", stdout);
    if (scanf (" %c %c", &z1, &z2) != 2) {
        fputs ("(input canceled before 2 characters read)\n", stderr);
        return 1;
    }

    if (getline (&buf, &n, fp) == -1) { /* read line from file into buf */
        fprintf (stderr, "error: reading from '%s'.\n", argv[1]);
        return 1;
    }
    fclose (fp);    /* close file */

    p1 = strchr (buf, z1);  /* locate z1 in buf */
    if (p1 == NULL) {       /* validate pointer not NULL */
        fprintf (stderr, "error: '%c' not found in buf.\n", z1);
        return 1;
    }   /* locate/validate z2 found after z1 in buf */
    else if ((p2 = strchr (p1, z2)) == NULL) {
        fprintf (stderr, "error: '%c' not found after '%c' in buf.\n",
                z2, z1);
        return 1;
    }   /* validate z2 is not next char after z1 */
    else if (p2 - p1 == 1) {
        fprintf (stderr, "error: '%c' is next char after '%c' in buf.\n",
                z2, z1);
        return 1;
    }
    p1++;   /* increment p1 to point to 1st char between z1 & z2 */

    /* allocate mem for chars between p1 & p2 */
    if ((btwn = malloc (p2 - p1 + 1)) == NULL) {
        perror ("malloc-btwn");
        return 1;
    }

    memcpy (btwn, p1, p2 - p1); /* copy characters between p1 & p2 */
    btwn[p2 - p1] = 0;          /* nul-terminate btwn */

    printf ("between: '%s'\n", btwn);   /* output results */

    free (btwn);    /* don't forget to free the memory you allocate */
    free (buf);
}

示例输入/文件

$ cat ../dat/qbfox.txt
A quick brown fox jumps over the lazy dog.

使用/输出示例

$ ./bin/findcharsbtwn ../dat/qbfox.txt
enter beginning and ending characters: j s
between: 'ump'

$ ./bin/findcharsbtwn ../dat/qbfox.txt
enter beginning and ending characters: A f
between: ' quick brown '

错误顺序:

$ ./bin/findcharsbtwn ../dat/qbfox.txt
enter beginning and ending characters: s j
error: 'j' not found after 's' in buf.

两个字符都不在buf中:

$ ./bin/findcharsbtwn ../dat/qbfox.txt
enter beginning and ending characters: B z
error: 'B' not found in buf.

$ ./bin/findcharsbtwn ../dat/qbfox.txt
enter beginning and ending characters: A B
error: 'B' not found after 'A' in buf.

z1z2之间什么都没有:

$ ./bin/findcharsbtwn ../dat/qbfox.txt
enter beginning and ending characters: w n
error: 'n' is next char after 'w' in buf.

(不要忘记在Linux上使用诸如valgrind之类的工具来验证您的内存使用情况)

仔细检查一下,如果还有其他问题,请告诉我。