【问题标题】:C Programming - fgets() infinite while loopC 编程 - fgets() 无限循环
【发布时间】:2015-06-22 06:03:26
【问题描述】:

我在从文本文件中获取增强矩阵时遇到问题。在成功地从文本文件中读取所有数据后,程序将简单地发生段错误,很可能是因为它仍在寻找另一个要到达的令牌或 fgets() 没有达到 NULL 状态?老实说,我迷路了……

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "apmatrix.h"
#define NUMARGS 2 
#define BUFSIZE 128

int main (int argc, char *argv[]) 
{ 
    /* Matrices that will always be used */
    Matrix* A;
    Vector* b;
    Vector* x;
    iVector* p;

    /* Used in LU factorization */
    Matrix* L;
    Matrix* U;

    /* Standard character read-in variables needed */
    char sep[] = " "; /* parsing separator is space */
    char *z,*buffer;  /* buffer and pointer to scan buffer */
    FILE *ifp;        /* source file */ 
    unsigned buflen;  /* length of line read */
    int flag, count;
    int Rows,Columns;/* to hold number read */
    int CurrentRow=0;

    /* first check to see if have required number for argc */ 
    /* if not, error has occurred, don't do anything else */ 
    if (argc == 2 || argc==3) 
    { 
        /* correct number of arguments used, try to open both files */ 
        buffer = (char*) malloc(BUFSIZE); /* allocate buffer */
        ifp = fopen (argv[1], "r");  /* open file for reading */ 

        if (ifp && buffer) { /* if successful proceed */
            /* read file line by line */
            flag=0;
            while (fgets(buffer, BUFSIZE, ifp) != NULL) {       
                /* defensive/secure programming */
                buflen = strlen(buffer);
                /* parse line */            
                z = strtok(buffer,sep);

                /* take in the values of the rows and columns */
                if(flag == 0){
                    ++flag;                 /* Flag = 1 */

                    Rows = atoi(z);         /* Convert the string to double */
                    printf("  %d",Rows);
                    z = strtok(NULL, sep);  /* find next number */
                    Columns = atoi(z);      /* Convert the string to double */           
                    printf("  %d",Columns);
                    putchar('\n');

                    A = m_alloc(Rows,Columns);
                    b = v_alloc(Rows);
                    x = v_alloc(Rows);
                    p = iv_alloc(Rows);

                    L = m_alloc(Rows,Columns);
                    U = m_alloc(Rows,Columns);
                }
                /* take in the values of the matrices */
                else{

                    for(int i = 0; i < Rows; i++){
                        A->mat[CurrentRow][i] = (Real) atof(z);             /* Convert the string to an int*/
                        z = strtok(NULL, sep);  /* find next number */
                        printf("   %2.3f   ",A->mat[CurrentRow][i]);
                    }

                    b->vec[CurrentRow] = (Real) atof(z);            /* Convert the string to an int */
                    printf("   %2.3f   ",b->vec[CurrentRow]);           
                    putchar('\n');
                    CurrentRow++;
                    putchar('\n');
                }

            } 
            fclose (ifp); 

...

我没有打印我的其余代码,因为我只是不认为它与手头的问题相关。我想知道为什么会出现这个问题以及如何在代码中修复它,因为稍后我需要在程序中解决 Ax=b 的信息。文本文件为我提供了增广矩阵 [A|b],因此我使用 LU 分解求解 x。我认为这可能与缓冲区本身有关,但我对 C 编程也缺乏经验。

我正在阅读的文本文件也是这样写的......

 3 4
 2 1 1  1
 6 2 1 -7
-2 2 1  7 

这些是我从代码中得到的结果

  3  4
   2.000      1.000      1.000      1.000

   6.000      2.000      1.000      -7.000

   -2.000      2.000      1.000      7.000

Segmentation fault (core dumped)

感谢您的宝贵时间。 :)

更新:我尝试运行 gdb 进行调试,但一直坚持尝试使用文本文件运行核心转储。 (例如 ./hw6 ge1.txt 是我在命令行中输入的内容)。如何使用文本文件运行它,因为没有它会出现段错误。

 c
Continuing.
Expecting two or three arguments
The second argument must be a text file to read from.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400a4e in m_free (M=0x0) at apmatrix.c:32
32              free(M->mat[0]); /* free data */

【问题讨论】:

  • 挂钩 GDB 并尝试查找导致崩溃的行?
  • 无限循环或分段错误?你不可能同时有这两个问题。
  • z = strtok(NULL, sep); Columns = atoi(z); 不检查是否z === NULL
  • 尝试验证buflen是否为0!如果为0,则不执行字符串解析,(我认为您可能会破坏while,但我不确定它是否正确!但是如果您看到程序在buflen变为0后仍然处于循环状态,那么就破坏while是正确的方式)。

标签: c while-loop fgets file-read


【解决方案1】:
1) compile your program with -ggdb parameter
2) link your program with the -ggdb parameter

这将生成一个包含最大数量的调试信息的可执行文件,可供 gdb 调试器使用。

3) assure the source code is visible from where the program is to be run
   (in the same directory works very well)
4) at the command line: gdb yourProgramName
5) from within gdb enter the following commands
    br main    <-- sets breakpoint at main
    run        <-- execution program until breakpoint reached
    c          <-- continue execution
6) when the program crashes, enter the following commands
   bt          <-- display a back trace
7) examine the back trace to see which line your program crashed on.

8) quit y      <-- to exit the program
9) let us know which line that is.  
   paste/edit the line into your question
   as a line number would be meaningless to us.

【讨论】:

    猜你喜欢
    • 2013-03-17
    • 2017-01-18
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    相关资源
    最近更新 更多