c - 将字符串的地址传递给 fscanf() 会阻止不相关的代码块运行

标签 c file loops file-io io

我一直在开发一个小型 C 程序,它从文件中读取字符串,使用 crypt() 对其进行加密,然后将加密版本写入字符串。由于某种原因,我没有思考并将 fscanf 调用编写为:

fscanf( filename, "%s", &string );

这不起作用,因为字符串已经表示为指针,但这样做:

fscanf( filename, "%s", string );

这个逻辑(读取、测试、加密、打印)是在循环中完成的。在循环之前,我有几行代码将程序信息打印到日志文件中:

fprintf( logfile, "Called as %s\n", executable );
/* Etc... */

在我意识到 fscanf 的错误之前,我注意到在程序收到 SIGSEGV 后,创建的日志文件是空的。首先我尝试了一个循环:

while(1)
{
  fprintf( logfile, "Looped!\n");
}

这一直有效,直到我输入读取、测试、加密、打印序列。我意识到我的错误是什么,但我的问题是: 为什么对字符串的不正确读取(总是出现段错误)会阻止完全不相关的代码块运行?

编辑:这是“工作”代码(加密仍然存在段错误):

fprintf( logfile, "Called as %s\n", executable );
fprintf( logfile, "Assigned pid %lu\n", pid );
fprintf( logfile, "Input File: %s\n", inputfilename );
fprintf( logfile, "Output File: %s\n", outputfilename );
fprintf( logfile, "Default BUFFER: %lu\n", BUFFER );
fprintf( logfile, "Crypt output sixe: %lu\n", CRYPT_OUTPUT_SIZE );
fprintf( logfile, "\n" );

/*  Try to set up space for strings */
fprintf( logfile, "Attempting to allocate %lu chars(%u) for plaintext string...\n", BUFFER,sizeof(char) );
char *plaintext_string = (char *) calloc( BUFFER, sizeof(char) );
if( plaintext_string == NULL )
{
    fprintf( logfile, "Errno %d; Error %s; Trying to allocate %lu chars(%u) for plaintext string\n",
    errno, strerror(errno), BUFFER,sizeof(char) );
    return(STRERROR);
}

fprintf( logfile, "Success; Now attempting to allocate %lu bytes for encrypted string...\n", CRYPT_OUTPUT_SIZE );
char *encrypted_string = (char *) calloc( CRYPT_OUTPUT_SIZE, sizeof(char) );
if( encrypted_string == NULL )
{
    fprintf( logfile, "Errno %d; Error %s; Trying to allocate %lu chars(%u) for encrypted string\n",
    errno, strerror(errno), (unsigned long) CRYPT_OUTPUT_SIZE, sizeof(char) );
    return(STRERROR);
}

fprintf( logfile, "\n" );

fprintf( logfile, "Entering main loop\n" );
while( TRUE )
{
    int res = fscanf( inputfile, "%s", plaintext_string );
    if( res == EOF )
    {
        fprintf( logfile, "Reached EOF in %s; Breaking from loop\n", inputfilename );
        break;
    }

    if( plaintext_string == NULL )
    {
        fprintf( logfile, "Errno %d; Error %s; String read in from %s was NULL\n", errno, strerror(errno), inputfilename);

        free(plaintext_string);
        free(encrypted_string);
        fclose(logfile);
        fclose(inputfile);

        return(STRERROR);
    }

    strcpy( encrypted_string, crypt( plaintext_string, SALT ) );
    if( encrypted_string == NULL )
    {
        fprintf( logfile, "Errno %d; Error %s; Encrypted string was NULL\n", errno, strerror(errno) );

        free(plaintext_string);
        free(encrypted_string);
        fclose(logfile);
        fclose(inputfile);

        return(STRERROR);
    }

    fprintf( outputfile, "%s\n", encrypted_string );

    /*  Clear the strings so no data is held    */
    *plaintext_string = NULL;
    *encrypted_string = NULL;
}

谢谢!

——乔丹。

最佳答案

默认情况下,写入日志文件会被缓冲。当程序因段错误而崩溃时,缓冲区永远不会被刷新。使用 setvbuf(logfile, _IONBF); 关闭缓冲,或者在您希望缓冲区转到文件时刷新缓冲区:

fprintf( logfile, "Called as %s\n", executable );
fflush(logfile);

关于c - 将字符串的地址传递给 fscanf() 会阻止不相关的代码块运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54489491/

相关文章:

swift - Heroku:如何读取文件?

Python 使用一个函数循环到其他函数。

c - linux中如何避免sleep调用因信号中断?

c - 测试链表

ruby-on-rails - Ruby:遍历目录和文件

计算 C 文件中未知数量的字符

java - 如果控制台可以打印大于 2 的值,为什么控制台不会在 FOR 循环中打印小于 2 的 i 值?

loops - 如何解析CF结构体

C fread() 和缓冲区管理

c++ - 关于数据对齐和填充的另一个混淆