逐行读取文件 - 为什么我只获得第一行?

时间:2016-12-06 13:14:20

标签: c file-io readfile

我在大学里有一项任务是编写一个C程序,它读取一个文件并计算单个和多个注释的数量。我遇到的问题是第二个while()只读取第一行,因此返回的注释为0.

以前我逐个字符地读取文件,但这不是任务要求。为什么这个程序只读取第一行而不读其他行?

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

int main(int argc, char **argv) {
    FILE *fp;
    int c, i = 0;
    char path[256], ch, line[80];
    unsigned int multi  = 0;
    unsigned int single = 0;

    enum states { 
        PLAIN_TEXT, 
        SLASH, 
        STAR, 
        SINGLE_COMMENT, 
        MULTI_COMMENT,
        QUOTES 
    } state = PLAIN_TEXT;

    printf("Write file's name\n");
    gets(path)

    fp = fopen(path, "r");
    if (!fp) {
        // give an error message
    } else {        
        while (fgets(line, sizeof(line), fp) != NULL) {         
            while (i < sizeof(line)) { 
                printf("%d.%c", i, line[i]);
                switch (state) {
                  case PLAIN_TEXT:
                    switch (line[i]) {
                      case '/': i++; 
                        state = SLASH; 
                        break; // found a slash. In the next loop the switch argument will be SLASH
                      case '"': i++;
                        state = QUOTES; 
                        break; // found a quote. Quoted text (there might be a '//' inside)
                      default: i++;
                        break; // found an ordinary character
                    }
                    break;
                  case QUOTES: 
                    switch (line[i]) {
                      case '"': i++;
                        state = PLAIN_TEXT; 
                        break; // Gets out the string;
                      case ' ':i++;
                        state = PLAIN_TEXT;
                        break; 
                      default: i++;
                        state = QUOTES; 
                        break; // Still a quoted text;
                    }
                    break;
                  case SLASH:
                    switch (line[i]) {
                      case '/': i++;
                        state = SINGLE_COMMENT; 
                        break; // found a slash => a possible single comment found
                      case '*': i++;
                        state = MULTI_COMMENT; 
                        break; // found a star => a possible multi comment found
                      default: i++;
                        state = PLAIN_TEXT; 
                        break; // found an ordinary character
                    }
                    break;
                  case STAR:
                    switch (line[i]) {
                      case '/': i++;
                        state = PLAIN_TEXT; 
                        multi++;
                        break; // Increments the multi comment and the next characher will be treated as a plain_taxt
                      default: i++;
                        state = MULTI_COMMENT; 
                        break; // Still multi comment
                    }
                    break;
                  case SINGLE_COMMENT:
                    switch (line[i]) {
                      case '\n':i++;
                        state = PLAIN_TEXT; 
                        single++; 
                        break; // End of the single comment line. Increment the counter and the next character will be treated as a plain_text
                      default: i++;
                        break;
                    }
                    break;
                  case MULTI_COMMENT:
                    switch (line[i]) {
                      case '*': i++;
                        state = STAR; 
                        break; // Found a multi comment. The next state will be star.
                      default: i++;
                        break;
                    }
                    break;
                  default: i++;
                    break;
                }
            }   
        }
        fclose(fp);
        printf("Single-comment : %8u\n", single);
        printf("Multi-comment : %8u\n", multi);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

要枚举该行上的字符,您必须为每一行重新初始化{{1}}为0并停在空终止符或换行符