繁体   English   中英

逐字读取文件并输出空格

[英]Read file word by word and output WITH white spaces

输入文本文件如下所示:

Hello my
name is 
mark.
and
im 
going
to
love
c!

码:

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

 int main(int argc, char *argv[]){
FILE *pFile;
char x[60];

pFile = fopen("test0.txt","r");

if(pFile != NULL){
    while(fscanf(pFile, " %60s", x) == 1){
        printf("%s",x);
 }

}
}

输出文本文件为:

Hellomynameismark.andimgoingtolovec!

我希望输出是这样的:

Hello my name is mark. and im going to love c!

非常新的C程序员,所以只知道基础知识。

编辑 - -

   int main(int argc, char *argv[]){
FILE *pFile;
char x[60],line[60];

pFile = fopen("test0.txt","r");

while(!feof(pFile)){

        fgets(line, 60, pFile);
        strtok(line, "\r\n");
        printf("%s", line );
    }
    fclose(pFile);

输出:

 Hello myname is mark.andim goingtolovec!

这不会在新行之间留空格。 但是,如果我删除strtok行,输出将如下所示:

Hello my
name is 
mark.
and
im 
going
to
love
c!

- 编辑

 .sp 2
 .ce
 This is an example file for formatting.
 .sp 1
 The above line
 was formatted using a .ce 1 command, which means 'centre
 the following line',
 so it should appear in the 
 centre of the page.
 The paragraph was separated from the heading using
 a .sp 1 command to create a single blank line.
 There should also be two blank lines above the centred heading to make            reading it slightly easier.

简单的答案是:

while(fscanf(pFile, " %59[^\n]%*c", x) == 1)

这里, %[^\\n]使用字符类[stuff]读取所有内容,直到换行符为止。 %*c只是读取并丢弃换行符,而不将其添加到fscanf的匹配计数中。

但是,对于面向行的输入,您应该真正使用标准库提供的面向行的功能之一(例如fgets或POSIX getline )。

使用fgets和strtok

正如您从评论中摘录的那样,使用feof给您带来悲伤。 您将只需要使用fgets的返回来确定文件结尾。 这是将难题的所有部分放在一起的示例:

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

#define MAXWDS  20
#define MAXCHR  60

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

    char line[MAXCHR] = {0};
    char *words[MAXWDS] = {NULL};
    FILE *pFile = NULL;
    size_t i, index = 0;

    /* open file for reading (if provided), or read from stdin */    
    if (!(pFile = argc > 1 ? fopen (argv[1], "r") : stdin)) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (fgets (line, 60, pFile)) 
    {
        char *p = line;

        /* split line into tokens, stored in words[] */
        for (p = strtok (p, " \r\n"); p; p = strtok (NULL, " \r\n")) {
            words[index++] = strdup (p); /* allocate & copy */

            if (index == MAXWDS)    /* check pointer limit */
                break;
        }

    }
    if (pFile != stdin) fclose (pFile);

    /* output in a single line */
    for (i = 0; i < index; i++) {
        printf (" %s", words[i]);
        free (words[i]);            /* free allocated memory */
    }

    putchar ('\n');

    return 0;
}

gcc -Wall -Wextra -o bin/fgets_strtok fgets_strtok.c 

产量

$ ./bin/fgets_strtok dat/hellomark.txt
 Hello my name is mark. and im going to love c!

注意:只要将各行之间的空格打印出来,只要每行中各个单词之间已经有空格,就没有理由麻烦将每行分隔为单个单词了,您可以只需以空格分隔的方式打印出每一行的内容。 使用fgets遇到的唯一问题是,它还会读取newline (或carriage return, newline )作为字符串的一部分。 这很容易删除。 您可以将整个读取循环替换为:

while (fgets (line, 60, pFile)) 
{
    size_t len = strlen (line);

    /* strip trailing newline (or carriage return newline ) */
    while (len && (line[len-1] == '\n' || line[len-1] == '\r'))
        line[--len] = 0;  /* overwrite with null-terminating char */

    words[index++] = strdup (line); /* allocate & copy */

    if (index == MAXWDS)    /* check pointer limit */
        break;
}

产量

$ ./bin/fgets_mark <dat/hellomark.txt
 Hello my name is mark. and im going to love c!

仅读取文件的标准方式(不读取文件或标准输入)

很抱歉为您带来一些麻烦,其中包括一种打开文件(如果在命令行中提供)或从stdin读取(如果未提供文件名)的方法。 标准方法是首先检查命令行上是否提供了正确数量的参数,然后打开所提供的文件名,确认文件名已打开,然后处理输入。 我所做的就是将ternary operator放入上述的fopen命令中。

pFile = argc > 1 ? fopen (argv[1], "r") : stdin

'='符号的右侧是三元运算符,它只是if- if -> then -> else then- if -> then -> else的简写。 它要问的是argc > 1吗? 如果测试结果为true ,则pFile = fopen (argv[1], "r"); 如果argc > 1测试为false ,则pFile = stdin;

看看标准方法是否更有意义:

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

#define MAXWDS  20
#define MAXCHR  60

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

    char line[MAXCHR] = {0};
    char *words[MAXWDS] = {NULL};
    FILE *pFile = NULL;
    size_t i, index = 0;

    /* validate sufficient input */
    if (argc < 2 ) {
        fprintf (stderr, "error: insufficient input, usage: %s filename\n", argv[0]);
        return 1;
    }

    /* open file provided on command line for reading */
    pFile = fopen (argv[1], "r");
    if (!pFile) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (fgets (line, 60, pFile)) /* read each line in file */
    {
        size_t len = strlen (line);

        /* strip trailing newline (or carriage return newline ) */
        while (len && (line[len-1] == '\n' || line[len-1] == '\r'))
            line[--len] = 0;  /* overwrite with null-terminating char */

        words[index++] = strdup (line); /* allocate & copy */

        if (index == MAXWDS)    /* check pointer limit */
            break;
    }
    if (pFile != stdin) fclose (pFile);

    /* output in a single line */
    for (i = 0; i < index; i++) {
        printf (" %s", words[i]);
        free (words[i]);            /* free allocated memory */
    }

    putchar ('\n');

    return 0;
}

一个简单的状态机就能解决问题-没有行长限制。

#include <stdio.h>

 int main(void) {
   FILE *pFile = fopen("test0.txt","r");
   if(pFile != NULL) {
     int previous_isspace = 0;
     int ch;
     for (;;) {
       ch = fgetc(pFile);
       if (ch == EOF) break;
       if (isspace(ch)) {
         previous_isspace = 1;
       } else {
         if (previous_isspace == 1) {
           fputc(' ', stdout);
         }
         previous_isspace = 0;
         fputc(ch, stdout);
       }  
     }
     fclose(pFile);
     fputc('\n', stdout);   // If code should have a \n at the end
   }
 }

我认为,足够看一下我是否想念任何东西。

if(pFile != NULL){
      //  while(fscanf(pFile, " %60s", x) == 1){
            while (fgets(x, sizeof(x), pFile) != NULL) {
             token = strtok(x,"\r\n");
             if(token != NULL)
                    printf("%s ",x);
             else
                    printf("%s",x);
            }
            fclose(pFile);
    }

暂无
暂无

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

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