2012-10-25 28 views
0

这是我到目前为止,书写,打印在一个文件中的每一行的第一个字一个小的C程序

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

void main(int argc, char *argv[]){ 

    FILE *fp; 
    char word[30]; 
    int k; 
    for (k=1 ; k < argc ; k++) 
    { 
     fp = fopen(argv[k],"r"); 
     if (fp == NULL) 
     fprintf(stdout,"Error with file: %s\n",argv[k]); 
     else{ 
     while(!feof(fp)){ 
      fscanf(fp,%s%*[^\n]",word); 
      printf("word: %s\n",word); 
      memset(word,0,sizeof(word));      
     } 
     } 
    fclose(fp); 
    } 
} 

我不知道如果我有什么正确与否,还我一个不知道我应该在while循环中打印出文件中每行的每个第一个单词。帮助将非常感谢,预先感谢您的任何帮助/提示!

+0

你是否学过如何从文件中读取一行?另外,你是否需要处理多个文件?最后,不要忘了在完成阅读时关闭文件! –

+0

打印字符,直到达到空格,换行符或文件结尾。 – Max

+0

@Max - “直到你到达一个空间”=>“,直到你到达一个空间,_换行符或文件的末尾_” –

回答

1

一开始,可以取代:

int k = 1; 
for (k; k < argc; k++) 

与更“标准”:

int k; 
for (k = 1; k < argc; k++) 

然后,else部的内部,一个简单的循环和状态机,其将仅输出第一个字中的字符。基于字符的状态机的优点在于,线路的长度并不重要,并且不存在缓冲区溢出的可能性。

使用30个字符的缓冲区时,如果您尝试对一个文件(例如)上的60个字符进行一次一行处理,则可能会遇到问题。

下面的伪代码可以帮助:

state = before_word 
get character from input stream (see fgetc) 
while character is not end-of-file: 
    if character is newline: 
     echo character (see putchar) 
     state = before_word 
    else 
     if state is before_word: 
      if character is not white space (see isblank/isspace): 
       echo character 
       state = in_word 
      endif 
     else 
      if state is in_word: 
       if character is white space: 
        state = past_word 
       else 
        echo character 
       endif 
      endif 
     endif 
    endif 
    get character from input stream (see fgetc) 
endwhile 

它的工作原理是保持状态(你的状态根据已经通过输入流进来的东西是什么)。

初始状态为before_word,因为它紧接在文件第一行之前的假想换行符之后。在该状态下,所有空白字符都被丢弃,第一个非空白字符会在回应该字符后导致状态更改为in_word

当状态为in_word时,输出每个字符。不会输出在该状态下到达的第一个空白字符,并使状态转换为past_word

past_word状态下,所有字符都被丢弃。

在任何状态(此if声明是第一个),一个换行符迫使该州成为before_word

将伪代码转换为C代码对您来说是一个很好的练习,尤其是如果这是作业。


如果它不功课,解决方案遵循以下。警惕将此作为你自己的工作传递,因为SO是一个公共场所,我确信教育工作者检查这些网站是否为抄袭。一个简单的谷歌搜索echoAndChange几乎肯定会让你失败。

因此,在假设它不是做作业,或者你只是想要的东西来检查自己的解决方案对,在这里我们去:

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

// States and utility function for echo and change state. 

typedef enum {ST_PRE, ST_IN, ST_POST} tState; 

tState echoAndChange (int chr, tState newState) { 
    if (chr != EOF) putchar (chr); 
    return newState; 
} 

int main (int argc, char *argv[]) { 
    FILE *fp; 
    int k, chr; 
    tState state; 

    // Process each file. 

    for (k = 1; k < argc; k++) { 
     fp = fopen (argv[1], "r"); 
     if (fp == NULL) { 
      printf ("Error with file: %s\n", argv[1]); 
     } else { 
      // Initial state pre-word, then process every character. 

      state = ST_PRE; 
      while (1) { 
       chr = fgetc (fp); if (chr == EOF) break; 

       // Newline: output it and change to pre-word. 

       if (chr == '\n') { 
        state = echoAndChange (chr, ST_PRE); 
        continue; 
       } 

       // Pre-word and nonspace: echo and change to in-word. 

       if (state == ST_PRE) { 
        if (!isblank (chr)) 
         state = echoAndChange (chr, ST_IN); 
        continue; 
       } 

       // In-word: change to post word if space, otherwise echo. 

       if (state == ST_IN) 
        if (isblank (chr)) 
         state = echoAndChange (EOF, ST_POST); 
        else 
         state = echoAndChange (chr, ST_IN); 
      } 
      fclose (fp); 
     } 
    } 
    return 0; 
} 

当运行在著名的“Lorem存有”文本程序:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna 
aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat. 
Duis aute irure dolor in reprehenderit in voluptate velit 
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint 
occaecat cupidatat non proident, sunt in culpa qui officia 
deserunt mollit anim id est laborum. 

你可以看到它在行动:

Lorem 
sed 
aliqua. 
ullamco 
Duis 
esse 
occaecat 
deserunt 

如果你想有一个程序,你可以像吸收了一些状态机进入为了中,你的语句执行(不担心前导空格):

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

int main (int argc, char *argv[]) { 
    FILE *fp; 
    int echo, chr; 

    if (argc < 2) { 
     puts ("Usage: firstword <input-file>"); 
     return -1; 
    } 

    fp = fopen (argv[1], "r"); 
    if (fp == NULL) { 
     printf ("Error with file: %s\n", argv[1]); 
     return -1; 
    } 

    echo = 1; 
    chr = fgetc (fp); 
    while (chr != EOF) { 
     if (chr == '\n') echo = 1; 
     if (isblank (chr)) echo = 0; 
     if (echo) putchar (chr); 
     chr = fgetc (fp); 
    } 
    fclose (fp); 
    return 0; 
} 

这里的基本规则是:

  • 初始状态是回声。
  • 然后,对于每个字符:
    • 换行符强制回显(换行符回显两行)。
    • 任何空白页都会回显。
    • 如果回显,字符会被回显。
+0

我实际上正在考试,这是我必须知道如何去做的。这是过去几年测试中的一个测试问题,我必须知道准备这个测试。唯一让你感到困扰的是,它应该是一个“小”的答案,可以写在测试代码中。 –

+0

@ Michael_19,我在最后添加了一个较短的变体。 – paxdiablo

1

有几种方法可以做到这一点。一种方法是使用getline()读取文件中的行由行,然后打印的字符,直到第一个空白字符:

#include <ctype.h> 

char *line = NULL; 
size_t siz = 0; 
int i = 0; 

while(-1 != getline(&line, &siz, fp)){ 
    for(i = 0; i < siz && !isspace(line[i]); i++){ 
     printf("%c", line[i]); 
    } 
} 

这仍然留下了一些边缘情况进行处理(空行等),但它应该让你开始。

+2

请注意'getline'不是C标准的一部分。它可能在某些实现中可用,但不能保证。 – paxdiablo

+0

不打算添加该头文件。更新了我的代码,但出于某种原因在最后打印了一个空白字。 –

相关问题