如何从 fgets 中获取正在读取的行的长度并对其进行循环

How to get the length of the line being read in from fgets and loop over it

我试图遍历 fgets 中一行的每个字符,但我 运行 出错了,我将在下面解释。

int main(int argc, char* argv[]) {
   char arr[200]
   int currS = sizeof(arr) / sizeof(char);
   // call readIt function

}

void readIt(char* argv[], char arr[], int currS) {
  FILE* file;
  file = NULL;
  file = fopen(argv[1], "r");
  while(fgets(arr, currS, file) != NULL) 
    for (int i = 0; i < sizeof(arr); i++) 
       print each char of current line
}

当我对每一行执行 for 循环时,每一行输出将是文件中第一行的长度。 for 循环迭代的次数永远不会改变。我该如何更新它?我查看了其他 SO 问题,但它们不是很有帮助..

readIt()函数中,你需要strlen(arr),而不是sizeof arr。后者会给你 char * 的大小,无论它可能指向的字符串的长度如何,它总是相同的。

您还应检查 fopen() 中的 return 是否不是 NULL,因为 fopen() 可能因多种原因而失败。

void readIt(char* argv[], char arr[], int currS) {
    FILE * file = fopen(argv[1], "r");
    if ( file ) {
        while( fgets(arr, currS, file) ) {
            const int len = strlen(arr); 
            for ( int i = 0; i < len; ++i ) {
                // print each char of current line
            }
        }
    }
}

请注意,在这里使用变量 len 意味着您只计算一次字符串的长度,然后再开始循环它,而不是每次循环都计算它,如果您这样做了for ( int i = 0; i < strlen(arr); ++i )。如果您所做的只是打印每个字符,那么字符串的长度不会在两次调用 fgets() 之间发生变化,因此多次计算它是低效的。

此外,除非出于某种原因您希望 main() 中的数组包含在 readIt() return 之后从文件中读取的最后一行,否则您可以更轻松地定义 arrreadIt() 本身中,以避免将它传递给该函数的需要,例如:

void readIt(char* argv[]) {
    FILE * file = fopen(argv[1], "r");
    if ( file ) {
        char arr[200];
        while( fgets(arr, sizeof arr, file) ) {
            const int len = strlen(arr); 
            for ( int i = 0; i < len; ++i ) {
                // print each char of current line
            }
        }
    }
}

因为 arr 现在是 readIt() 中的实际数组,而不是指向 char 的指针(您不能将数组传递给函数,只能传递一个数组的地址), sizeof arr 将为您提供数组的实际大小,而不是 char * 的大小,因此您可以将其传递给 fgets().

这个函数:

void readIt(char* argv[], char arr[], int currS) {
  FILE* file;
  file = NULL;
  file = fopen(argv[1], "r");
  while(fgets(arr, currS, file) != NULL)
    for (int i = 0; i < sizeof(arr); i++)
       print each char of current line
}

最好使用 arr[]
中的实际字符数 建议使用牙套,避免日后许多维护问题
建议使用垂直间距以提高可读性
建议使用注释来避免将来的许多维护问题

void readIt(char* argv[], char arr[], int currS)
{
    FILE* file = NULL;

    if( NULL == (file = fopen(argv[1], "r") ) )
    { // then fopen failed
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    // read line from file and echo to user
    // note: file lines are considered to be terminated by either a NUL char or newline or EOF
    //       fgets() assures the line in arr[] has a NUL char termination
    while( fgets(arr, currS, file) )
    {
        int len = strlen(arr);  // returns offset to NUL char

        // use following if do not want to echo a newline read from the file
        if( '\n' == arr[strlen(arr)-1])
        {
            arr[strlen(arr)-1] = '[=11=]';
            len--;
        } // end if

        printf( "\nNumber of characters in line: %d\n", len );
        printf( "%s\n", arr );

    } // end while

    fclose(file); // cleanup
} // end function: readIt